如何通过 child 在 child 列表上的索引更新状态

How to update state by child's index on child list

我有一个像这样的简单项目列表:

const nodeList = Array.from({length:10}, (_,i) => i + 1)
const Counter = () => {
    
    const [count, setCount] = React.useState(0)  
    return (
      <div>
       {nodeList.map((node,i) => (
          <div key={i}>
            <button 
              onClick={() => {
                setCount(prev => prev + 1)
              }}
            >
              Sum up
            </button>
            <span>{count}</span>
          </div>
        ))}
        
      </div>
    )
  }

但是当我点击总和时,所有元素的计数值都相同,我如何使用 child 获得列表中每个 child 独立的计数值的键或索引?

我想尝试另一种方法,而不是使用单个数字,我想使用 Object 并根据单击的项目创建状态,如下所示:

const [count, setCount] = useState({});

  const handleClick = (i) => {
    setCount({ ...count, [i]: 1 });
  };
  return (
    <div className="App">
      {nodeList.map((node, i) => (
        <div key={i}>
          <button
            onClick={() => {
              handleClick(i);
            }}
          >
            Sum up
          </button>
          <span>{count[i]}</span>
        </div>
      ))}
    </div>
  );

现在,如何让每个元素的计数器增加?

问题是你的状态未启动。所以 count[i] 是未定义的,不会呈现,并且 undefined + 1 returns NaN.

这是修复问题的代码沙箱:https://codesandbox.io/s/summer-pond-v2isz?file=/src/App.js

我使用 count[i] || 0 到 return 0 如果 count 是“假的”(https://developer.mozilla.org/en-US/docs/Glossary/Falsy),并将 setCount({ ...count, [i]: 1}); 更改为 setCount({ ...count, [i]: (count[i] || 0) + 1 });

最好用 useStatelistItem 状态创建为数组并使用 index 更新它。

LIVE CODESANDBOX

请务必从 set 函数创建一个 克隆数组 和 return,因为如果您在同一个数组中进行更改,它不会反映出来。

HOW NOT TO UPDATE AN ARRAY

import { useState } from "react";

const Counter = () => {
  const [listItem, setListItem] = useState(Array(10).fill(0));

  function increment(index) {
    setListItem((prev) => {
      const clone = [...prev];
      clone[index] += 1;
      return clone;
    });
  }

  return (
    <div>
      {listItem.map((node, i) => (
        <div key={i}>
          <button onClick={() => increment(i)}>Sum up</button>
          <span>{node}</span>
        </div>
      ))}
    </div>
  );
};

export default Counter;