Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

209
Vistas
React useState changes all elements in an array in array of objects

I have 2 states product and variations I call an API and set the values of both state to the API response.

I want the product state to stay as it is and not update

  const [product, setProduct] = useState({} as any);
  const [variations, setVariations] = useState([] as any);

  useEffect(() => {
    const getProduct = async () => {
      const data = await axios.get("/products?id=4533843820679");
      console.log(data);
      setProduct(data.data);
      // @ts-ignore
      setVariations([data.data]);
    };
    getProduct();
  }, []);

In return I map the variations array and return inputs for title, and price and a button to add variations. Adding variations will add another product to variations array. So it just pushes product to variations.

Then I have inputs for title in variation and prices in variation.variants. The problem is with onChange.

When I change the price of one element in variants it changes for all and also changes it for PRODUCT state.

The code can be found here: https://codesandbox.io/s/smoosh-firefly-6n747?file=/src/App.js

Add variations, change prices add another variations and you'll see all issues I'm facing.

about 4 years ago · Juan Pablo Isaza
3 Respuestas
Responde la pregunta

0

It is because of this:

 variant.price = e.target.value; // same issue with title

the variant object reference is shared among variations and you are modifying it directly. It is shared because you you made a shallow copy of a variation using ... when adding it.

Here is the solution:

You should update the specific variant object in immutable way (in react you should always update state in immutable way). For that you need to use this as onChange for price:

onChange = {
    (e) => {
        let updated = variations.map((x) => {
            if (x.id === variation.id) {
                return {
                    ...x,
                    variants: x.variants.map((y) => {
                        if (y.id === variant.id) {
                            return {
                                ...y,
                                price: e.target.value
                            };
                        }
                        return y;
                    })
                };
            }
            return x;
        });
        setVariations(updated);
    }
}

This for onChange for title:

onChange = {
    (e) => {
        let updated = variations.map((x) => {
            if (x.id === variation.id) {
                return {
                    ...x,
                    title: e.target.value
                };
            }
            return x;
        });
        setVariations(updated);
    }
}

NOTE but ids of variations must be different. For testing purposes you can use this as click handler when adding a new variation:

onClick = {
    () => {
        setVariations((prev) => [...prev, {
            ...product,
            id: Math.floor(Math.random() * 1000) // for testing
        }]);
    }
}
about 4 years ago · Juan Pablo Isaza Denunciar

0

First, you are not pushing the product to variations. You are overwriting it.

To push a value to array with useState,

setVariations([...variations, product])

But, if you change the product object, variations also gonna be change because it's the same object. (Maybe, react not gonna re-render it but trust me, it is changed.) If you want to keep it same you need to create new object.

So,

setProduct(data.data);
setVariations([...variations, {...data.data}]);

Now, you can change product. variations not gonna change.

about 4 years ago · Juan Pablo Isaza Denunciar

0

This was because you did a shallow copy of an object.

Try to do like this:

setVariations([...variations, data.data,]);
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda