Reputation: 2748
I have a list of tag objects in array (tagList), which I am fetching from the server and storing into the state. After a succesfull fetch I am mapping each item inside a ScrollView
.
export default class RegisterTags extends Component {
constructor(props) {
super(props)
this.state = {
tagList: [],
selectedTags: [],
}
}
componentWillMount() {
api.getTagsOnRegister()
.then((res) => {
this.setState({
tagList: res
})
})
}
insertTag = (tag) =>{
this.setState({
selectedTags: this.state.selectedTags.push(tag)
})
}
render() {
return(
<View style={styles.container}>
<ScrollView contentContainerStyle={styles.ScrollViewContainer}>
{this.state.tagList.map((tag) => {
return(
<View style={styles.tagStyle} key={tag.id} onPress={this.insertTag(tag)}>
<Text style={styles.tagText}>{tag.name}</Text>
</View>
)
})}
</ScrollView>
</View>
)
}
}
What I want to achieve is, when I press on any of the tag, I would like to add that object into the selectedTags array. But I am getting error:
Warning: setState(...): Cannot update during an existing state transition (such as within
render
or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved tocomponentWillMount
.Possible Unhandled Promise Rejection (id: 0): _this.state.selectedTags.push is not a function TypeError: _this.state.selectedTags.push is not a function
How can I add the pressed tag item into the selectedTags array?
Upvotes: 2
Views: 9498
Reputation: 32107
onPress={this.insertTag(tag)}
Issue: in your render
function you are directly calling a function that changes state. Render
function should never call any function that updates state.
So how to call onPress
?
Ans: as written below
onPress = {() => {this.insertTag(tag) }}
Will code work now? Answer is no.
You have to put your views inside TouchableHighlight
and move onPress
method from View
to TouchableHighlight
.
Then hopefully your code works. I am assuming everything is setup property.
~~~~~~EDIT 1~~~~~~~~
What't the difference between onPress={this.insertTag(tag)}
and onPress = {() => {this.insertTag(tag) }}
Every thing inside curly braces are expressions in react jsx. Now onPress={this.insertTag(tag)}
evaluates the expression inside curly braces and assign it to onPress property, and in your case this.insertTag
happens to update state.
While onPress = {() => {this.insertTag(tag) }}
, on evaluating curly braces returns a function, but doesn't call that function. And when onPress event is triggered than that function is called.
Google "Arrow Function" for more.
Upvotes: 3