繁体   English   中英

常见问题解答部分个别切换不正确点击打开所有部分

[英]FAQ's section individual toggle incorrectly opening all parts on click

我一直在尝试做一种切换,这样您就可以点击一个问题来展开答案。 我试过改编来自https://codesandbox.io/s/polished-rain-xnez0?file=/src/App.js的代码,这是来自此处的另一个问题。

我没有在父组件中创建 map 并将它们分别传递给可重用的“可扩展”组件以呈现单独的功能组件,而是尝试在 FAQ 组件中创建 map:

常见问题扩展组件:

const FAQ = ({ questions }) => {

const [expanded, setExpanded] = useState(false);

const handleClick = () => {
    setExpanded((prevExpanded) => !prevExpanded);
  };

const renderedQuestions = questions.map((question, index) => {

    return (
        <React.Fragment key={question.id}>
            <FAQIndividualWrapper>
                <FAQTitle 
                    className='title'
                    onClick={() => handleClick()}
                >
                    {/* <i></i> */}
                    {question.title}
                </FAQTitle>
                <FAQContent className='content' style={{ display: expanded ? "block" : "none" }}>
                    {question.content}
                </FAQContent>
            </FAQIndividualWrapper>
        </React.Fragment>
    )
})


return (
    <>
    {renderedQuestions}
    </>
)

父组件:

const questions = [
{
    id: 1,
    title: 'Question 1',
    content: 'Answer 1'
},
{
    id: 2,
    title: 'Question 2',
    content: 'Answer 2'
}
]

const FAQSection = () => {
    return (
        <FAQPageContainer>
            <FAQWrapper>
                <FAQ questions={questions} />
            </FAQWrapper>

        </FAQPageContainer>
    )
}

但是,我的代码会导致所有答案都在任何一个问题的任何点击中展开。 为什么会这样?

另外,我应该如何构建和修复“理想”编程的代码?

谢谢!

您的代码的问题是您只有一个expanded的 state 可以解决所有问题。 这意味着打开/折叠 state 对于所有问题都是相同的。

如果您想将所有代码包含在一个组件中。 您需要以某种方式区分每个孩子的打开/折叠 state。

在这里,我使用一个数组来存储每个孩子的个人打开/折叠 state。

  // initial state is an array with the length of your questions array, default to false
  const [expandedIndexes, setExpandedIndexes] = useState(
    Array(info.length).fill(false)
  );
 
  const handleClick = (index) => {
    setExpandedIndexes((prevExpandedIndexes) => {
      const newState = [...prevExpandedIndexes];
      // set state for the corresponding index
      newState.splice(index, 1, !prevExpandedIndexes[index]);
      return newState;
    });
  };
  return (
    <div className="details">
      {info.map(({ title, details, id }, index) => (
        <div key={id} className="details-wrapper">
          <div>
            <h3 className="title">{title}</h3>
            <button onClick={() => handleClick(index)}>+</button>
          </div>
          <p
            className="text"
            // check the corresponding state to display
            style={{ display: expandedIndexes[index] ? "block" : "none" }}
          >
            {details}
          </p>
        </div>
      ))}
    </div>
  );

代码沙盒

另外,我应该如何构建和修复“理想”编程的代码?

理想情况下,您希望遵循上面代码和框链接中的约定。 这样你就不需要处理这种逻辑,每个孩子都会有自己的状态/handleClick function。

正确的是,问题是由您只有一个 boolean state 引起的。

使用 object 存储扩展问题的id ,为每个问题切换 boolean 值。

例子:

const FAQ = ({ questions }) => {
  const [expanded, setExpanded] = useState({});

  // Curried callback to enclose the id in callback scope
  const handleClick = id => () => {
    setExpanded(expanded => ({
      ...expanded,
      [id]: !expanded[id],
    }));
  };

  return questions.map((question) => (
    <FAQIndividualWrapper key={question.id}>
      <FAQTitle
        className='title'
        onClick={handleClick(question.id)}
      >
        {question.title}
      </FAQTitle>
      <FAQContent
        className='content'
        style={{ display: expanded[question.id] ? "block" : "none" }}
      >
        {question.content}
      </FAQContent>
    </FAQIndividualWrapper>
  ));
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM