San*_*agi 7 javascript reactjs redux react-redux
I have my redux state like this:
{
parks: [
{
_id:"ad1esdad",
fullName : "Some Name"
},
{
_id:"ad1es3s",
fullName : "Some Name2"
}
],
parkInfo: {
id : "search Id",
start_time : "Some Time",
end_time : "Some Time"
}
}
Run Code Online (Sandbox Code Playgroud)
I have a parkSelector component from which a user selects parkId and start_time and end_time
import React, { Component } from 'react';
import { changeParkInfo } from '../../Actions';
class ParkSelector extends Component {
constructor(props) {
super(props);
this.handleApply = this.handleApply.bind(this);
this.rederOptions = this.rederOptions.bind(this);
this.state = {
startDate: moment().subtract(1, 'days'),
endDate: moment(),
parkId : this.props.parks[0]
};
}
handleApply(event) {
this.setState({
parkId : event.target.parkId.value
startDate: event.target.start_time.value,
endDate: event.target.end_time.value,
});
this.props.changeParkInfo(this.state.parkId,this.state.startDate,this.state.endDate);
}
rederOptions(){
return _.map(this.props.parks,(park,index)=>{
return(
<option value={park._id} key={park._id}>{park.profile.fullName}</option>
);
});
}
render() {
return (
<div className="row">
<div className="pb-4 col-sm-3">
<form onSubmit={this.handleApply}>
<select name="parkId" value={this.state.parkId} className="form-control input-sm">
{this.rederOptions()}
</select>
<input name="start_time" type="date" />
<input name="end_time" type="date" />
<button type="submit">Apply</button>
</form>
</div>
</div>
)
}
}
function mapStateToProps(state){
return {
parks : state.parks
};
}
export default connect(mapStateToProps,{ changeParkInfo })(ParkSelector);
Run Code Online (Sandbox Code Playgroud)
I have another component 'stats' which needs to displays information related with parkInfo which will be loaded my api request.
import React, { Component } from 'react';
import StatsCard from '../../components/StatsCard';
import { getDashboardStats } from '../../Actions';
class Dashboard extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div className="animated fadeIn">
<div className="row">
<StatsCard text="Revenue Collected" value={9999} cardStyle="card-success" />
<StatsCard text="Total Checkins" value={39} cardStyle="card-info" />
<StatsCard text="Total Checkouts" value={29} cardStyle="card-danger" />
<StatsCard text="Passes Issued" value={119} cardStyle="card-warning" />
</div>
</div>
)
}
}
function mapStateToProps(state){
return {
parkInfo : state.parkInfo,
dashboardStats : state.dashboardStats
};
}
export default connect(mapStateToProps,{ getDashboardStats })(Dashboard);
Run Code Online (Sandbox Code Playgroud)
I need to call getDashboardStats action (which makes api call and stores in results in dashboardStats of the redux state) whenever the redux state of parkInfo changes.
What is the best way to call this action, I have tried componentWillUpdate but it keeps on updating infinitely. What is best practice for this scenario ?
目标:redux-state 的变化parkInfo应该促使 Dashboard 调度getDashboardInfo并重新渲染。(此行为在其他组件中也类似)。
我使用 babel transform-class-properties,语法略有不同。
例子:
// SomeLayout.js
import ParkSelector from 'containers/ParkSelector'
import Dashboard from 'containers/Dashboard'
const SomeLayout = () => {
return (
<div>
<ParkSelector />
<Dashboard />
</div>
)
}
export default SomeLayout
Run Code Online (Sandbox Code Playgroud)
-
// Dashboard.js
// connect maps redux-state to *props* not state, so a new park selection
// will not trigger this component to re-render, so no infinite loop there
@connect((store) => ({ currentParkId: store.parkInfo.id }, //decorator syntax
{ getDashboardStats })
)
class Dashboard extends Component {
state = {
currentId: this.props.currentParkID,
parkInfoFoo: '',
parkInfoBar: ''
}
// using null for when no park has been selected, in which case nothing runs
// here.
componentWillReceiveProps(nextProps) {
// when Dashboard receives new id via props make API call
// assumes you are setting initial state of id to null in your reducer
if (nextProps.currentParkId !== null) {
getDashboardStats(`someurl/info/${nextProps.id}`).then((data) => {
// update state of Dashboard, triggering a re-render
this.setState({
currentId: nextProps.id
parkInfoFoo: data.foo,
parkInfoBar: data.bar
})
})
}
}
render() {
const { currentId, parkInfoFoo } = this.state
if (currentId !== null) {
return <span>{parkInfoFoo}</span>
}
return null
}
}
export default Dashboard
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10925 次 |
| 最近记录: |