Reputation: 21536
I've got a component which takes a list from my apps state, and I want to filter that list based on the input of a text field in the component. When the user filters the list they can then select an item from the list and that will update the state.
It seems to me that having the filter as part of the apps state is not valuable, as the filter itself is only needed for this component.
My redux state is
onst mapStateToProps = (state) => {
return {
tracks: Object.keys(state.activities).map(a => {
return {
id: state.activities[a].id,
user: state.activities[a].user,
color: state.activities[a].color
}})
};
}
const mapDispatchToProps = (dispatch) => {
return {
setTarget: (targetId) => {
dispatch(setTargetPointsById(targetId))
}
}
};
const TrackSelectorControl = connect(mapStateToProps, mapDispatchToProps)(TrackSelector);
export default TrackSelectorControl;
and then in my component, I have
lass TrackSelector extends Component {
componentWillMount() {
this.setState({filter: false})
}
componentWillReceiveProps(props, state) {
}
componentDidUpdate(props, state) {
}
shouldComponentUpdate() {
return false;
}
filter() {
if (!this.state.filter) return this.props.tracks
return this.props.tracks.filter(t => {
return t.user.name.includes(this.state.filter)
})
}
render() {
return <ul className={style.list}>
<input type="text" placeholder="Filter" onChange={(evt) => {
this.setState({filter: evt.target.value});
}} />
{this.filter().map(track => {
return <li key={track.id} onclick={this.props.setTarget(track.id)} className={style.track}>
<img style={{borderColor: createColor(track.color) }} src={track.user.avatar} className={style.img} />
<span>{track.user.name} </span>
</li>
})}
</ul>
}
}
export default TrackSelector;
The error I get is warning setState({...}) cannot update...
Upvotes: 1
Views: 513
Reputation: 281686
You are getting this error because when you write
<li key={track.id} onclick={this.props.setTarget(track.id)} className={style.track}>
you are calling the setTarget
function onClick
but since you are calling it like
onclick={this.props.setTarget(track.id)}
it means that onClick
is assigned a value and not a function since it takes the return value of this.props.setTarget(target.id)
.
So everytime your component renders
this function will be called automatically without the event to fetch the value and since you are setting a state in that function you are getting a warning.
You need to bind this function like
onclick={this.props.setTarget.bind(this, track.id)}
and it will solve the problem
Upvotes: 1