如何在使用 React 单击另一个详细信息时自动关闭打开的详细信息标签?

How to automatically close an open details tag when another detail is clicked with React?

问题

我有一个 detail 标签列表,我希望在另一个标签打开时关闭一个打开的 details 标签。

我正在动态呈现 details 标签列表

堆栈

我正在使用 React 和 hooks

我的尝试

我将打开属性设置为使用 useState 并在单击 details 标记时更新,但这似乎不起作用。

这是一个link到一个code sandbox

import { useState } from "react";

const arr = [
  { name: "Jim", age: 22 },
  { name: "Sarah", age: 42 },
  { name: "Don", age: 7 }
];

export default function App() {
  const [open, setOpen] = useState(false);

  const toggleDetails = (index) => {
    setOpen(!open);
  };
  return (
    <ul>
      {arr?.map((thing, index) => (
        <details key={index} open={open} onClick={() => toggleDetails(index)}>
          <summary>{thing.name}</summary>
          {thing.age}
        </details>
      ))}
    </ul>
  );
}

我添加了一个“id”键,如您的代码和框中所示,以执行以下操作,使用 toggleDetails 设置当前打开的详细信息的 id,然后在 open 道具检查数组中的当前对象id是否与状态的此匹配。

如果是,则 open 为真,否则为假。

import { useEffect, useState } from "react";

const arr = [
  { id: "03F03BBE", name: "Jim", age: 22 },
  { id: "D37DEF7F1E7E", name: "Julie", age: 42 },
  { id: "8D61", name: "Don", age: 7 }
];

export default function App() {
  const [openId, setOpenId] = useState('');

  const toggleDetails = (thingId) => {
    setOpenId(thingId);
  };

  return (
    <ul>
      {arr?.map((thing, index) => (
        <details key={index} open={openId === thing.id} onClick={() => toggleDetails(thing.id)}>
          <summary>{thing.name}</summary>
          {thing.age}
        </details>
      ))}
    </ul>
  );
}

这对我有用:

import { useState } from "react";

const faqs = [
  { id: "03F03BBE", name: "Jim", age: 22 },
  { id: "D37DEF7F1E7E", name: "Julie", age: 42 },
  { id: "8D61", name: "Don", age: 7 },
];

export default function App() {
  const [openFaqId, setOpenFaqId] = useState("");

  const clickActiveFaq = (id) => (e) => {
    e.preventDefault();
    setOpenFaqId(id !== openFaqId ? id : "");
  };

  return (
    <div>
      {faqs?.map((faq) => (
        <details
          key={faq.id}
          open={openFaqId === faq.id}
          onClick={clickActiveFaq(faq.id)}
        >
          <summary>{faq.name}</summary>
          {faq.age}
        </details>
      ))}
    </div>
  );
}