[英]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.