Israel Obanijesu
Israel Obanijesu

Reputation: 696

ReactJS: Change the index of an array in a state

I am trying to update the index of an array inside React state. The problem is that i cannot access the index of the array using setState() method.

My code looks like this:

handleLike(post) {
        axios.get(`/likes/${post}`)
            .then(response => {
                this.state.posts.forEach((entry, index) => {
                    if (entry.id === post) {
                        this.setState({posts[index]: response.data})
                    }
                })
            })
    }

I expect the array content to be updated with the response data but instead, it throws an error. How can I update the index of an array in React state?

Upvotes: 1

Views: 2802

Answers (2)

Mayank Shukla
Mayank Shukla

Reputation: 104529

The way you are setting data in setState is not correct. Write it like this:

handleLike(post) {
  axios.get(`/likes/${post}`)
    .then(response => {
      this.setState(prevState => ({ 
         posts: prevState.posts.map(el => el.id == post? response.data: el) 
      }))
    })
}

Why your code is not working?

Because posts[index] will be a value (object), and that will not a correct JS key.

To update the any value in state, you need to clone it first, do that changes, and pass the updated value to correct key in setState method.

Since you want to update a single object in array of objects, use updater function (because setState is async and new value will be dependent on previous value of state array), run map on array, return the new object for true condition, otherwise return the same object.

Example:

let stateArr = [{a:1, id:1}, {a:2, id:2}, {a:3, id:3}]

let newObj = {a: 10, id: 2}
const key = 2;

let newStateArr = stateArr.map(el => el.id == key? newObj: el);

console.log('old array', stateArr);
console.log('new array', newStateArr);

Upvotes: 5

Vencovsky
Vencovsky

Reputation: 31713

Try this

...
if (entry.id === post) {
    // get all of the posts in a new variable
    let newPost = [...post]
    // set only the index you want
    newPost[index] = response.data
    // set newPost to the state
    this.setState({post: newPost})
}

Upvotes: 1

Related Questions