Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

208
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda