在映射函数问题中反应条件样式

React conditional styling in a map function problem

我只想显示切换的项目。但是所有地图项目都出现了。基本上这是我从 onclick 得到的结果。我想我需要为每个项目提供索引或 ID,但我不知道该怎么做。我给每个问题都提供了 id 没有用。

App.js.

import "./App.css";
import React, { useState, useEffect } from "react";
import bg from "./images/bg-pattern-desktop.svg";
import bg1 from "./images/illustration-box-desktop.svg";
import bg2 from "./images/illustration-woman-online-desktop.svg";
import { data } from "./data";
import Faq from "./Faq";

function App() {
  const [db, setDb] = useState(data);
  const [toggle, setToggle] = useState(false);
  useEffect(() => {
    console.log(db);
  }, []);

  return (
    <>
      <div className="container">
        <div className="container-md">
          <div className="faq">
            <img src={bg} className="bg" />
            <img src={bg1} className="bg1" />
            <img src={bg2} className="bg2" />
            <div className="card">
              <h1>FAQ</h1>
              <div className="info">
                {db.map((dat) => (
                  <Faq
                    toggle={toggle}
                    setToggle={setToggle}
                    title={dat.title}
                    desc={dat.desc}
                    key={dat.id}
                    id={dat.id}
                  />
                ))}
              </div>
            </div>
          </div>
        </div>
      </div>
    </>
  );
}

export default App;
(地图来自我创建的简单 data.js 文件。它只包含 id title desc。)

Faq.js

import React from "react";
import arrow from "./images/icon-arrow-down.svg";

const Faq = ({ toggle, setToggle, title, desc, id }) => {
  return (
    <>
      {" "}
      <div className="question" onClick={() => setToggle(!toggle)}>
        <p>{title}</p>

        <img src={arrow} className={toggle ? "ikon aktif" : "ikon"} />
      </div>
      <p className="answer border">{toggle ? <>{desc}</> : ""}</p>
    </>
  );
};

export default Faq;

您将需要 每个 切换的状态。这是一个最小的可验证示例。 运行 下面的代码,然后单击 ⭕️ 打开一个项目。点击关闭

function App({ faq = [] }) {
  const [toggles, setToggles] = React.useState({})
  const getToggle = key =>
    Boolean(toggles[key])
  const setToggle = key => event =>
    setToggles({...toggles, [key]: !getToggle(key) })
  return faq.map((props, key) =>
    <Faq key={key} {...props} open={getToggle(key)} toggle={setToggle(key)} />
  )
}

function Faq({ question, answer, open, toggle }) {
  return <div>
    <p>
      {question}
      <button onClick={toggle} children={open ? "❌" : "⭕️"} />
    </p>
    {open && <p>{answer}</p>}
  </div>
}

const faq = [
  {question: "hello", answer: "world"},
  {question: "eat", answer: "vegetables"}
]

ReactDOM.render(<App faq={faq} />, document.querySelector("#app"))
p { border: 1px solid gray; padding: 0.5rem; }
p ~ p { margin-top: -1rem; }
button { float: right; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.14.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.14.0/umd/react-dom.production.min.js"></script>
<div id="app"></div>

您需要存储切换项的索引值。 您可以使用现有代码库仅用 2 行修改代码。

import "./App.css";
import React, { useState, useEffect } from "react";
import bg from "./images/bg-pattern-desktop.svg";
import bg1 from "./images/illustration-box-desktop.svg";
import bg2 from "./images/illustration-woman-online-desktop.svg";
import { data } from "./data";
import Faq from "./Faq";

function App() {
  const [db, setDb] = useState(data);
  const [toggle, setToggle] = useState(-1); //Modify Here
  useEffect(() => {
    console.log(db);
  }, []);

  return (
    <>
      <div className="container">
        <div className="container-md">
          <div className="faq">
            <img src={bg} className="bg" />
            <img src={bg1} className="bg1" />
            <img src={bg2} className="bg2" />
            <div className="card">
              <h1>FAQ</h1>
              <div className="info">
                {db.map((dat, index) => ( //Modify Here
                  <Faq
                    toggle={index === toggle} //Modify Here
                    setToggle={() => setToggle(index)} //Modify Here
                    title={dat.title}
                    desc={dat.desc}
                    key={dat.id}
                    id={dat.id}
                  />
                ))}
              </div>
            </div>
          </div>
        </div>
      </div>
    </>
  );
}

export default App;



import React from "react";
import arrow from "./images/icon-arrow-down.svg";

const Faq = ({ toggle, setToggle, title, desc, id }) => {
  return (
    <>
      {" "}
      <div className="question" onClick={setToggle}>
        <p>{title}</p>

        <img src={arrow} className={toggle ? "ikon aktif" : "ikon"} />
      </div>
      <p className="answer border">{toggle ? <>{desc}</> : ""}</p>
    </>
  );
};

export default Faq;

而不是这样做(在 App 组件中):

 const [db, setDb] = useState(data);
 const [toggle, setToggle] = useState(false);

您可以像下面这样编写一个 useState 挂钩来组合这两个挂钩,并为每个 Faq[分配一个 isOpened 属性 =40=]元素:

const [db, setDb] = useState(data.map(value=>{return {...value, isOpened:false}}));

然后就在这里你可以这样做(作为 <div className="info"> 的 child):

{db.map((dat, index) => ( 
      <Faq
        toggle={dat.isOpened} 
        setToggle={() => toggleById(dat.id)} 
        title={dat.title}
        desc={dat.desc}
        key={dat.id}
        id={dat.id}
      />
))}

您还需要在 App 组件中声明 toggleById 函数:

const toggleById = (id) => {
   const newDb = db.map(dat=>{
       if(dat.id==id){
          return {...dat,isOpened:!dat.isOpened}
       }
       return dat;
   });
   setDb(newDb);
}

并且由于 FaqsetToggle prop,通过其定义的参数调用 toggleById,因此没有需要在 Faq 组件中执行此操作:

<div className="question" onClick={() => setToggle(!toggle)}>

你可以简单地写:

<div className="question" onClick={setToggle}>