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

229
Vistas
Updating specific values of matrix useState hook state variable

I am trying to update a matrix of 20x20 values, each slot is binded to a div, once a div is clicked, its background color should change.

What is the best way of doing this, without having to set the whole matrix?

Also, why do some set methods don't work, since most of these are used in examples through the internet?

import { useState } from "react";

function App() {
  const n = 20;

  // define [20][20] array with default value on each slot as { color: "red" }
  const [matrix, setMatrix] = useState(Array(n).fill(Array(n).fill({ color: "red" })))

  let updateCell = (i, j) => {
    console.log(i, j); // Works perfectly, returns i and j of the matrix slot binded to the clicked cell.

    // const mat = matrix; mat[i][j].color = "blue";                  // Doesnt work
    // setMatrix((mat) => { mat[i][j].color = "blue"; return mat; }); // Doesnt work
    // matrix[i][j].color = "blue"; setMatrix(matrix);                // Doesnt work
    // matrix[i][j].color = "blue"; setMatrix([...matrix]);           // Changes ALL squares instead of the one clicked.
    // const mat = Object.assign({}, matrix); setMatrix(mat);         // TypeError: matrix.map is not a function
  }

  return (

    <div className="container">

      {/* Renders all squares fine! */}
      {matrix.map((i, ipos) => {
        console.log(matrix.length);

        return (
          <div key={ipos} className="d-flex flex-row wrap">

            {i.map((j, jpos) => {
              console.log(i.length);
              return (

                <div
                  style={{ backgroundColor: matrix[ipos][jpos].color, minWidth: "5%", minHeight: "50px", textAlign: "center", color: "white" }}
                  key={ipos + ", " + jpos}
                  onClick={() => { updateCell(ipos, jpos) }}
                >
                  {ipos + ", " + jpos}
                </div>

              )
            })}

          </div>
        )

      })}

    </div>
  )
}

export default App;

Best regards, and thank you.

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

0

You need to update useing the setMatrix function, and need to pass a new Array to that function (when using hooks, always need to be a new reference/object):

const updateCell = (i, j) => {
  let newMatrix = matrix.slice(); // just to create a copy of the matrix
  newMatrix[i][j].color = "blue";
  setMatrix( newMatrix ); // this call will trigger a new draw
}

EDIT:
Also, Array(n).fill will put the same reference on every place of the matrix, so changing one value will update all of then (because all are the same value / reference).

Change the line

useState(Array(n).fill(Array(n).fill({ color: "red" })))

to:

useState( Array.from({ length: 20 }, () => Array.from({length: 20}, () => ({ color: 'red' })) ) )
about 4 years ago · Juan Pablo Isaza Denunciar

0

Answer made with the helps these comments (Chris G and RCC):

You're changing state in place; React won't update the component unless it's a completely new matrix array. The fourth variant should have no effect either. The fifth changes matrix from an array to an object, those don't have a map function since they aren't arrays.

You need to update useing the setMatrix function, and need to pass a new Array to that function (when using hooks, always need to be a new reference/object)

Yeah, the problem is how you're filling the array. { color: "red" } creates a single object, and all array elements contain/point to that single object. Changing the color property will do that for all elements.

  useEffect(() => {
    const n = 20;

    for (let i = 0; i < n; i++) {
      matrix[i] = [];
      for (let j = 0; j < n; j++) {
        matrix[i][j] = { color: "red", coords: [i, j] }
      }
    }

    setMatrix([...matrix]);

  }, [])

  let updateCell = (i, j) => {
    console.log(i, j);
    matrix[i][j].color = "blue";
    setMatrix([...matrix]);
  }
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