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

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

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

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