【问题标题】:How to show collapsible content correctly inside an array map?如何在数组映射中正确显示可折叠内容?
【发布时间】:2021-07-10 22:24:43
【问题描述】:

所以我制作了一个对象数组并映射该数组。我也做了一个简单的可折叠。 问题是,可折叠设备无法正常工作。它应该只显示用户点击的内容。 当用户单击属于 John Doe 的按钮时,可折叠项应显示属于他的状态。我的代码发生了什么,它显示了每个人的状态。我尝试了 key={index} 但仍然没有结果。

这是我目前的代码...

import { useState } from "react";

const App = () => {
  const [showCollapsible, setShowCollapsible] = useState(false);

  const myDatas = [
    {
      id: 1,
      fullName: "John Doe",
      age: 28,
      status: "On Duty",
    },
    {
      id: 2,
      fullName: "Jane Doe",
      age: 27,
      status: "Rest",
    },
    {
      id: 3,
      fullName: "James Doe",
      age: 32,
      status: "Take a leave",
    },
  ];

  return (
    <div>
      {myDatas.map((data, index) => {
        return (
          <div>
            <p>{data.fullName}</p>
            <p>{data.age}</p>
            <button
              key={index}
              onClick={() => setShowCollapsible(!showCollapsible)}
            >
              Status
            </button>
            {showCollapsible && <div>{data.status}</div>}
          </div>
        );
      })}
    </div>
  );
};

export default App;

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    您正在使用相同的单一布尔状态来切换所有的可折叠 div。相反,存储一些唯一标识映射元素的状态,例如数据的id 属性。使用 id 检查 div 是否应该折叠或可见。

    const App = () => {
      const [showCollapsible, setShowCollapsible] = useState({});
    
      const myDatas = [
        {
          id: 1,
          fullName: "John Doe",
          age: 28,
          status: "On Duty"
        },
        {
          id: 2,
          fullName: "Jane Doe",
          age: 27,
          status: "Rest"
        },
        {
          id: 3,
          fullName: "James Doe",
          age: 32,
          status: "Take a leave"
        }
      ];
    
      const toggleCollapsable = (id) => () => {
        setShowCollapsible((set) => ({
          ...set,
          [id]: !set[id]
        }));
      };
    
      return (
        <div>
          {myDatas.map((data) => {
            return (
              <div>
                <p>{data.fullName}</p>
                <p>{data.age}</p>
                <button onClick={toggleCollapsable(data.id)}>Status</button>
                {showCollapsible[data.id] && <div>{data.status}</div>}
              </div>
            );
          })}
        </div>
      );
    };
    

    抽象一个管理该状态的Collapsible 组件会更简洁一些。

    const CollapsibleDiv = ({ children }) => {
      const [showCollapsible, setShowCollapsible] = useState(false);
    
      return (
        <>
          <button onClick={() => setShowCollapsible((show) => !show)}>
            Status
          </button>
          {showCollapsible && children}
        </>
      );
    };
    
    const App = () => {
      const myDatas = [
        {
          id: 1,
          fullName: "John Doe",
          age: 28,
          status: "On Duty"
        },
        {
          id: 2,
          fullName: "Jane Doe",
          age: 27,
          status: "Rest"
        },
        {
          id: 3,
          fullName: "James Doe",
          age: 32,
          status: "Take a leave"
        }
      ];
    
      return (
        <div>
          {myDatas.map((data) => {
            return (
              <div>
                <p>{data.fullName}</p>
                <p>{data.age}</p>
                <CollapsibleDiv>
                  <div>{data.status}</div>
                </CollapsibleDiv>
              </div>
            );
          })}
        </div>
      );
    };
    

    【讨论】:

    • 哇,我从没想过会这么复杂。此外,干净的代码看起来很简单,但它确实有效。多谢,伙计!我会试着理解代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-12
    • 1970-01-01
    • 2013-11-10
    相关资源
    最近更新 更多