提问者:小点点

(react JS)每个可折叠元素的单独触发器(react可折叠)


如何使用单个useState(最好)为每个可折叠元素创建单独的触发器?

代码沙盒-https://codesandbox.io/s/separate-triggers-question-forked-vgs5b

应用程序。js

import React from "react";
import Collapsible from "react-collapsible";

function App() {
  const database = [
    { id: 1, name: "Name1", description: "Desc1" },
    { id: 2, name: "Name2", description: "Desc2" },
    { id: 3, name: "Name3", description: "Desc3" },
    { id: 4, name: "Name4", description: "Desc4" },
    { id: 5, name: "Name5", description: "Desc5" }
  ];

  const [items, setItems] = React.useState(database);
  const [open, setOpen] = React.useState(false);

  return (
    <div className="tracker_master">
      {items.map((item, index) => (
        <div onClick={() => setOpen(!open)} key={item.id}>
          {item.name.toUpperCase()}

          <Collapsible open={open}>
            <div>{item.description.toUpperCase()}</div>
          </Collapsible>
        </div>
      ))}
    </div>
  );
}

export default App;

共2个答案

匿名用户

为了使每个项目都有单独的触发器,我建议将每个元素抽象为具有自己打开状态的组件。

所以你可以这样做:

const Item = ({ item }) => {
  const [open, setOpen] = React.useState(false);
  return (
    <div onClick={() => setOpen(!open)} key={item.id}>
      {item.name.toUpperCase()}

      <Collapsible open={open}>
        <div>{item.description.toUpperCase()}</div>
      </Collapsible>
    </div>
  );
};

function App() {
  const database = [
    { id: 1, name: "Name1", description: "Desc1" },
    { id: 2, name: "Name2", description: "Desc2" },
    { id: 3, name: "Name3", description: "Desc3" },
    { id: 4, name: "Name4", description: "Desc4" },
    { id: 5, name: "Name5", description: "Desc5" }
  ];

  return (
    <div className="tracker_master">
      {database.map((item) => (
        <Item item={item} key={item.id} />
      ))}
    </div>
  );
}

沙盒示例

匿名用户

如果您想使用singleuseState,那么您的single state对象应该管理所有项的打开标志,如下所示(我已经更新了您的代码并测试了它的工作性能)。

openFlags是一种单一状态,它通过id维护每个项目的打开标志,并使用它触发协作并独立展开项目。

import React from "react";
import Collapsible from "react-collapsible";

function App() {
  const database = [
    { id: 1, name: "Name1", description: "Desc1" },
    { id: 2, name: "Name2", description: "Desc2" },
    { id: 3, name: "Name3", description: "Desc3" },
    { id: 4, name: "Name4", description: "Desc4" },
    { id: 5, name: "Name5", description: "Desc5" }
  ];

  const [items, setItems] = React.useState(database);
  let initialOpenFlags = {}
   items.forEach((i) => {
    initialOpenFlags = {
      ...initialOpenFlags,
      [i.id]: false
    };
  });
  const [openFlags, setOpenFlags] = React.useState(initialOpenFlags);

  return (
    <div className="tracker_master">
      {items.map((item, index) => (
        <div
          onClick={() =>
            setOpenFlags({ ...openFlags, [item.id]: !openFlags[item.id] })
          }
          key={item.id}
        >
          {item.name.toUpperCase()}

          <Collapsible open={openFlags[item.id]}>
            <div>{item.description.toUpperCase()}</div>
          </Collapsible>
        </div>
      ))}
    </div>
  );
}

export default App;