如何分别更新 array.map() 中元素的状态?

How to update state of elements from array.map() separately?

在我的代码中,我试图根据对象的背景数据检索背景图像,但是这些背景也会根据元素的状态而改变。

首先,我的数据数组如下所示:

   const Cube = [
      {
         name: "foo"
         faces: [
            {
               data: [
                  [{bonus: "bar", bg: "bar2"}],
                  ...
               ],
               ...
            },
            ...
         ],
         ...
      },
      ...
   ];

这就是我的 App.js 的样子:

  function App() {
    const [cellState, setCellState] = useState("inactive");

    return (
      <div className="App">
        <div id="cube-container">
          {Cube[0].faces[0].data.map((row) => {
            return row.map((cell, index) => {
              return (
                <img
                src={require(`./assets/cube/Square_Cube_Icon/${cell.bg}${
                  cellState === "inactive" ? "_Unlit" : "_Partial"
                }.png`)}
                alt={`${cell.bg} background`}
                className="cellItem"
                onClick={() => setCellState("active")}
                state={cellState}
                key={index}
              />
            );
          });
        })}
      </div>
    </div>
  );
}

问题是,在 4x4 网格输出中,如果我点击任何项目,而不是因为状态变化而改变被点击元素的背景,它会改变每个单元格的背景,这应该发生,因为 useState 是所有单元格共享的他们中的。 我怎样才能使地图功能的每个元素都有自己的状态,我可以单独更新?

找到解决方案:

将其分离为组件并将键和单元格值作为道具传递,然后在内部创建和操纵状态修复 issue.Selected 答案也解决了问题。

这是为未来的读者准备的解决方案。

App.js

function App() {
  return (
    <div className="App">
      <div id="cube-container">
        {CubeOfTruth[0].faces[0].data.map((row) => {
          return row.map((cell, index) => {
            return <CubeItem key={index} cell={cell} />;
          });
        })}
      </div>
    </div>
  );
}

CubeItem.js

function CubeItem({ cell, index }) {
  const [cellState, setCellState] = useState("inactive");

  return (
    <img
      src={require(`../assets/cube/Square_Cube_Icon/${cell.bg}${
        cellState === "inactive" || cellState === "partial" ? "_Unlit" : ""
      }.png`)}
      alt={`${cell.bg} background`}
      className="cellItem"
      onClick={() => setCellState("active")}
      state={cellState}
      key={index}
    />
  );
}

这是使用一个对象管理多个状态的简单方法,该对象的键代表您的单元格,值代表它是活动的还是非活动的。这也很容易概括,所以如果你添加更多的单元格,那么你所要做的就是将它添加到 initialState & 你的代码的其余部分应该按原样工作。

function App() {

   // const [cellState, setCellState] = useState("inactive");
    
    const initialState = {
      bar1: "inactive",
      bar2: "inactive",
      bar3: "inactive",
      bar4: "inactive",
    }

   const [cellState, SetCellState] = React.useState(initialState);

   const handleSetCellState = (key)  => {   
    setCellState({
     ...cellState,
     [key]: "active",
    });   
   }; 


    return (
      <div className="App">
        <div id="cube-container">
          {Cube[0].faces[0].data.map((row) => {
            return row.map((cell, index) => {
              return (
                <img
                src={require(`./assets/cube/Square_Cube_Icon/${cell.bg}${
                  cellState[cell.bg] === "inactive" ? "_Unlit" : "_Partial"
                }.png`)}
                alt={`${cell.bg} background`}
                className="cellItem"
                onClick={() => handleSetCellState(cell.bg)}
                state={cellState[cell.bg]}
                key={index}
              />
            );
          });
        })}
      </div>
    </div>
  );
}