使用 React Hooks 在 adding/removing 个 div 上应用 increment/decrement 个计数

Apply increment/decrement count on adding/removing divs with React Hooks

每次单击 div 并从列表中添加或删除时,我都会尝试添加和删除计数,到目前为止,我已经能够在 [=17] 时添加增量计数=] 被点击,但即使名称已被点击并添加到列表中,它仍会添加计数。我将 incrementCount() 放在了错误的位置,而且我还无法确定将 decrementCount() 添加到的位置。这对大多数人来说应该很容易。非常感谢你能帮忙或给我指出正确的方向 Link to sandbox 就在这里 ➡️ https://codesandbox.io/s/optimistic-hamilton-len0q?file=/src/Home.js:244-258

import { useEffect, useState } from "react";

export const List = (props) => {
  const [selectedNames, setSelectedNames] = useState([]);
  const [names, setNames] = useState([]);
  const [count, setCount] = useState(0);

  const decrementCount = () => {
    if (count > 0) setCount(count - 1);
  };

  const incrementCount = () => {
    setCount(count + 1);
  };

  useEffect(() => {
    props.title === "" && setNames(props.items);
  }, [setNames, props]);
  return (
    <div className="">
      <div className="">
        ⬇ Click on the names below to add them to the list
        {names &&
          names.map((item, index) => (
            <div
              key={`${props}-${index}`}
              onClick={() => {
                incrementCount();
                !selectedNames.includes(item) &&
                  setSelectedNames((oldValue) => [...oldValue, item]);
              }}
            >
              <div className="list-name">{item.name}</div>
            </div>
          ))}
      </div>
      <div className="count-box">
        {count}
        <span>selected</span>
      </div>
      <div
        className="unselect-all-box"
        onClick={() => {
          setSelectedNames([]);
          setCount(0);
        }}
      >
        Unselect all
      </div>
      {selectedNames &&
        selectedNames.map((format) => (
          <div key={format.id}>
            <div className="">{format.name}</div>
            <div
              className="remove-selected"
              onClick={() => {
                setSelectedNames(
                  selectedNames.filter((f) => f.name !== format.name)
                );
              }}
            >
              (Press HERE to remove name)
            </div>
          </div>
        ))}
    </div>
  );
};
export default List;


export const App = (props) => {
  const formats = [
    {
      id: "0001",
      name: "(1) Sam Smitty",
    },
    {
      id: "0002",
      name: "(2) Hong Mong",
    },
  ];

  return (
    <div>
      <List title="" items={formats} />
    </div>
  );
};

export default App;```

仅当项目不在数组中时才增加计数

onClick={() => {
                if(!selectedNames.includes(item)){
                  incrementCount();
                  setSelectedNames((oldValue) => [...oldValue, item]);
                }
              }}

我觉得你是over-complicating东西有点。据我所知,count 状态只是 selectedNames 数组长度的“派生状态”。当您可以计算 selectedNames 数组的长度时,确实没有必要 increment/decrement 计算选定的名称。

删除 increment/decrement 处理程序并使用 selectedNames 数组长度。通过推导选定的计数,无需手动计数。

<div className="count-box">
  {selectedNames.length}{" "}
  <span>selected</span>
</div>

export const List = (props) => {
  const [selectedNames, setSelectedNames] = useState([]);
  const [names, setNames] = useState([]);

  useEffect(() => {
    props.title === "" && setNames(props.items);
  }, [setNames, props]);

  return (
    <div className="">
      <div className="">
        ⬇ Click on the names below to add them to the list
        {names?.map((item, index) => (
          <div
            key={`${props}-${index}`}
            onClick={() => {
              !selectedNames.includes(item) &&
                setSelectedNames((oldValue) => [...oldValue, item]);
            }}
          >
            <div className="list-name">{item.name}</div>
          </div>
        ))}
      </div>
      <div className="count-box">
        {selectedNames.length} <span>selected</span>
      </div>
      <div
        className="unselect-all-box"
        onClick={() => {
          setSelectedNames([]);
        }}
      >
        Unselect all
      </div>
      {selectedNames?.map((format) => (
        <div key={format.id}>
          <div className="">{format.name}</div>
          <div
            className="remove-selected"
            onClick={() => {
              setSelectedNames(
                selectedNames.filter((f) => f.name !== format.name)
              );
            }}
          >
            (Press HERE to remove name)
          </div>
        </div>
      ))}
    </div>
  );
};