0

How can I change a specific object in a state for example, I have data like this

const colors= [
      {
        id: 1,
        name: "red",
      },
      {
        id: 1,
        name: "green",
      },
      {
        id: 2,
        name: "blue",
      },
    ];

const storage = [{
id:2,
name:"64 GB"
},
{
id:2,
name:"128 GB"
]

The state value should be like this [{id:1, name:'red"}, {id:2,name:"128GB"}]

Is there any way to update the state based on the id only? For example: I need to loop on the data and if the state.id === id it will update that specific object. So in our example, I need to update the state to be [{id:1, name:'green"}, {id:2,name:"128GB"}] if the state.id === 1

Thanks in advance

3
  • create new object using Array.map Commented Aug 2, 2021 at 13:01
  • would you like to update colors or storage? which on is your state? Commented Aug 2, 2021 at 13:02
  • both are in my state and i want to update them based on the input data Commented Aug 2, 2021 at 13:05

2 Answers 2

2

You could always copy the current value in local var, modify and set again the state. Something like:

const [colors, setColor] = useState([
  {
    id: 1,
    name: "red",
  },
  {
    id: 1,
    name: "green",
  },
  {
    id: 2,
    name: "blue",
  },
]);

...

let colorCopy = Object.assign({}, colors); //<-- make a copy of color
colorCopy = colorCopy.map(x => { 
   if (x.id === 1) x.name = "black";
   return x;
}; // modify name property for id === 1
setColor(colorCopy); //<-- set new state

EDIT

@Nicolas Menettrier and @andy mccullough raised a good point of discussion: "Why call Object.assign if map function already does a copy of colors array?" This is correct so you could also write above code in this way:

let colorCopy = colors.map(x => { 
   if (x.id === 1) x.name = "black";
   return x;
}; // modify name property for id === 1
setColor(colorCopy); //<-- set new state

1 line code less.

Sign up to request clarification or add additional context in comments.

3 Comments

Why use Object.assign({}, colors) on an array? Why 'make a copy' when .map will create a new array anyway and why are you trying to reassign colorCopy when it is a const ?
Why not just doing a color.map ? It will return a new Array and it will not alter the state
@NicolasMenettrier @andy Yes, in this case I think we could directly do let colorCopy = colors.map(...)
1

You can update your array state of objects with a shallow copy and change the value, same as bellow:

import * as React from "react";

export default function App() {
  const [colors, setColors] = React.useState([
    {
      id: 1,
      name: "red"
    },
    {
      id: 1,
      name: "green"
    },
    {
      id: 2,
      name: "blue"
    }
  ]);
  const updateState = (id, name) => {
    let copy = [...colors];
    let color = copy.filter((x) => x.id == id)[0];
    if (!color) return;
    let index = copy.indexOf(color);
    color.name = name;
    copy[index] = color;
    setColors(copy);
  };
  return (
    <div className="App">
      {colors.map((color, index) => (
        <>
          <p>
            {color.id} : {color.name}
          </p>
        </>
      ))}
      <button
        onClick={() => {
          updateState(2, "yellow");
        }}
      >
        update
      </button>
    </div>
  );
}

Edit mutable-wildflower-n10ys

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.