I would like to pass data from my state to a fetch call (e.g. search term). When the state changes, it should re-fetch my data.
The lifecycle methods seem to be the place to do this, but when I use them it either does nothing (render is called before state change), or it goes on an endless loop.
Here is my simplified code:
@connect((store) => {
return {
collections : store.collections.collections
}
}, {
fetchCollections
})
export default class CollectionPane extends Component {
constructor(props){
super(props);
this.state = {
term : null
}
}
componentWillMount(){
this.handleFetchCollections(this.state.term); // This loads initial ok
}
componentDidUpdate(){
// this.handleFetchCollections(this.state.term); // This causes loop
}
handleFetchCollections(props, sort){
log('Fetching...', 'green');
this.props.fetchCollections(props, sort);
}
onSearch(){
const term = "test example";
this.setState({
term
})
}
render(){
const { collections } = this.props;
return (
<div>
<a style={{ display: "block", padding: "1em" }} onClick={this.onSearch.bind(this)}>Search</a>
<CollectionList collections={collections} />
</div>
);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react-dom.min.js"></script>
You should compare your new state with the previous state before performing fetch:
componentDidUpdate(prevProps, prevState) {
if (prevState.term !== this.state.term) {
this.handleFetchCollections(this.state.term);
}
}
With react-redux you should change your state through actions and reducers. Then you can use async actions as described here: http://redux.js.org/docs/advanced/AsyncActions.html