0

If we have an array that contains objects that each contain and array of tags like shown below:

const arr = [
  {
    0: {
      name: 'Apple',
      tags: ['fruit', 'green']
    }
  },
  {
    1: {
      name: 'ball',
      tags: ['round']
    }
  },
  {
    2: {
      name: 'cat',
      tags: ['grey', 'meow', 'treats']
    }
  }
];

Is it possible to use react hooks to update the array of tags? I was trying something like this but got confused:

setArr((prev => 
            ([...prev,
            ({...prev[id],
            [...prev[id]['tags'],
            prev[id]['tags']: newArrOftags ]})],
        ));
3
  • You need to first identify the index of the object you are trying to update, or use a map() Commented Sep 16, 2021 at 21:34
  • I have the index identified already. In fact, it works when I use the regular javascript method: arr[id]['tags'] = newArrOfTags; However, it does not re-render immediately so I have to use hooks. Commented Sep 16, 2021 at 21:41
  • You may want to rethink your strategy with your object structure, if indeed that is an accurate representation of your structure (use console.log(JSON.stringify(arr, null, 2)) to get a better picture). Commented Sep 16, 2021 at 22:52

2 Answers 2

1

Here's the simplest syntax that I would use to target a specific item in your array, given you know the number value used within that item, and then update the previous state within your useState hook:

const lookup = 1; // Using the correct number value to target ball
const newItem = 'Additional ball tag here';
  
setArr((prevArr) => {
    const newArr = prevArr.map((item) => {
        if (item[lookup]) {
            item[lookup].tags = [...item[lookup].tags, newItem];
        }

        return item;
    });

    return newArr;
});
Sign up to request clarification or add additional context in comments.

Comments

0

Instead of using short hand syntax which is a bit complex in your case, here is what you need. I am looping through the array using map and finding the object with id. Then appending the tags to that object's tags array. In the example I am adding a few tags to an object with id 1.

let arr = [
  {
    0: {
      name: 'Apple',
      tags: ['fruit', 'green']
    }
  },
  {
    1: {
      name: 'ball',
      tags: ['round']
    }
  },
  {
    2: {
      name: 'cat',
      tags: ['grey', 'meow', 'treats']
    }
  }
];

const id = 1;
const tags = ["test1","test2","test3"]

arr = arr.map((a)=>{
  
  if(Object.keys(a).includes(id.toString()))
  {
    a[id].tags = [...a[id].tags,...tags];
  }
  return a;
})

Use the above logic instead of spread operator to set state. map returns a new array so it's safe to use for state updates.

Here is an example of the logic: https://stackblitz.com/edit/js-xqnjai

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.