Benjamin Smith Max
Benjamin Smith Max

Reputation: 2748

Insert the pressed item into an array in react-native

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 to componentWillMount.

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

Answers (1)

Praveen Prasad
Praveen Prasad

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

Related Questions