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

169
Visualizações
Why is changing the array in a state, changing the original array in useState?

I have a default array (genreOptions) I pass to useState in my ShuffleControls function to initialise with. I have a button that changes one array value in the stored array in the state. But when updating the state, it also causes the change of the same value in the original array which I don't want.

This is stopping my plan to also use the original array to reset state array values from a button and to possibly use it elsewhere. I have tried making a clone of the original array and passing that in.

const genreOptions = [
  ["rock", true],
  ["pop", true],
  ["punk", true],
  ["acoustic", true],
  ["alternative", true],
  ["ambient", true],
  ["blues", true],
  ["classical", true],
  ["chill", true],
  ["comedy", true],
  ["country", true],
  ["dance", true],
  ["disco", true],
  ["electronic", true],
  ["folk", true],
  ["drum and bass", true],
  ["dub", true],
  ["funk", true],
  ["gospel", true],
  ["garage", true],
  ["hip hop", true],
  ["house", true],
  ["indie", true],
  ["jazz", true],
  ["metal", true],
  ["new age", true],
  ["opera", true],
  ["r&b", true],
  ["reggae", true],
  ["rock and roll", true],
  ["ska", true],
  ["soul", true],
  ["soundtracks", true],
  ["techno", true],
  ["world music", true],
];

var genreOptClone = [...genreOptions];

function ShuffleControls({ nextTrack, currentTrack, token: receivedToken }) {
    const [genres, setGenres] = useState(genreOptClone.sort());

  const handleGenreClick = (g, i) => {
    // toggle bool for genre
    g[(i, 1)] = !g[(i, 1)];
    setGenres([...genres]);
  };

  return (
    <div>
       {genres.map((g, i) => (
            <button
              type="button"
              key={i}
              onClick={() => {
                handleGenreClick(g, i);
                console.log("genreOptions onClick: ", genreOptions);
              }}
              className={g[(i, 1)] ? "genres-btn" : "genres-btn btn-disabled"}
            >
              {g[(i, 0)]}
            </button>
          ))}
   </div>
  );
}

export default ShuffleControls;
about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

You're only creating a shallow copy of the array with [...genreOptions], so changes to the array elements result in a change to the original array. A similar example:

const arr = [['foo', 'bar']];
const shallowClone = [...arr];
shallowClone[0].push('baz');
console.log(arr);

Change

const [genres, setGenres] = useState(genreOptClone.sort());

to

const [genres, setGenres] = useState(() =>
  genreOptions.map(subarr => [...subarr]).sort()
);

and, because mutation should be avoided in React, the following should be fixed (and using the comma operator there doesn't make any sense either)

  const handleGenreClick = (g, i) => {
    // toggle bool for genre
    console.log(g);
    g[(i, 1)] = !g[(i, 1)];
    setGenres([...genres]);
  };

Instead, only pass the index, and use:

const handleGenreClick = (i) => {
    setGenres(
        genres.map((g, j) => j !== i ? g : (
            [g[0], !g[1]]
        ))
    );
};

I'd also personally recommend using a data structure that indicates the values, rather than using less-intuitive array indicies - eg, instead of

["rock", true]

you might have

{
  name: 'rock',
  enabled: true
}

It'll be a bit easier and more intuitive to work with.

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