映射时 React 钩子状态未更新

时间:2021-03-02 22:53:26

标签: reactjs react-hooks state

我试图在用户点击按钮时更新一行按钮。我的按钮存储在我映射的状态。当我使用 console.log 时,我可以看到网格状态发生变化,但它不会重新呈现我的按钮。我哪里出错了?

const Step = ({ active, changeGridByVal, val }) => {
  return <>
    <button onClick={() => changeGridByVal(val)}>{active ? 'X' : 'O'}</button>
  </>
}

const TryPage = () => {

  const [grid, setGrid] = useState([
    ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '']
  ])

  function changeGridByVal(val){
    const note = val[0]
    const step = val.substring(2)
    const copy = grid
    copy[note][step] = 'X'
    setGrid(copy)
    console.log(grid)
  }
  
  return <> 
    {grid[0].map((e, i) => {
      return <Step key={i} val={`0-${i}`} changeGridByVal={changeGridByVal} active={e === '' ? false : true}></StepNote>
    })}
    </>
}

2 个答案:

答案 0 :(得分:2)

  function changeGridByVal(val){
    const note = val[0]
    const step = val.substring(2)
    const copy = grid
    copy[note][step] = 'X'
    setGrid(copy)
    console.log(grid)
  }

copy 实际上不是副本,而是原始数组,只是名称不同。当您设置状态时,react 在旧状态和新状态之间执行 === 并看到它们是相同的数组,因此它不会重新渲染。

相反,您需要创建一个新数组,这意味着在您更改的每个级别都创建一个副本:

function changeGridByVal(val){
    const note = val[0]
    const step = val.substring(2)
    const copy = [...grid];
    copy[note] = [...grid[note]];
    copy[note][step] = 'X';
    setGrid(copy)
  }

答案 1 :(得分:0)

尽管您创建了状态数组的“副本”,但您正在直接改变状态。但坦率地说,如果我正确理解了您的小应用程序,那么有一种更简单的方法可以将它们组合在一起。

您似乎只是想在 O 和 X 之间切换按钮。我希望您这样做:

import { useState } from "react";

const Step = ({ active, changeGridByVal, index }) => (
  <button onClick={() => changeGridByVal(index)}>{active ? "X" : "O"}</button>
);

const TryPage = () => {
  const [grid, setGrid] = useState([["O", "O", "O", "O", "O", "O"]]);

  const changeGridByVal = (index) => {
    setGrid([
      grid[0].map((btn, i) => {
        if (index === i) return btn === "O" ? "X" : "O";
        else return btn;
      })
    ]);
  };

  return (
    <>
      {grid[0].map((e, i) => {
        return (
          <Step
            key={i}
            index={i}
            changeGridByVal={changeGridByVal}
            active={e !== "O"}
          ></Step>
        );
      })}
    </>
  );
};

export default TryPage;

沙盒:https://codesandbox.io/s/admiring-worker-hoxyg?file=/src/App.js

相关问题