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

172
Vistas
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 Respuestas
Responde la pregunta

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 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