#javascript #reactjs #redux
#javascript #reactjs #redux
Вопрос:
У меня следующее замедление: const [open1, setOpen1] = useState(false);
и я хотел бы сгенерировать это столько, сколько я извлекаю записей из базы данных (для каждой извлеченной записи), мне нужен new [open, setopen]
вот мой цикл for, используемый в моем коде.
<Container fluid={true} className="text-center">
<div
className="questionrectangle "
onClick={() => setOpen1(!open1)}
name="step-one"
aria-controls="example-collapse-text"
aria-expanded={open1}>
<p className="questiontext "> {post.QString}</p>
</div>
<Collapse in={open1} name="step-two">
<p className="questionanswer">{post.Answer}</p>
</Collapse>
</Container> ```
If you have any idea I would be appreciated
Комментарии:
1. Это не очень хорошая идея. Почему вы не хотите иметь дело
setOpen
только один раз вContainer
?2. Когда я использую его только один раз, это влияет на другие элементы. я имею в виду, что все элементы сворачиваются вместе, когда я нажимаю на один из них.
3. Правильно, вам нужно будет настроить prop с уникальным идентификатором. Тогда ваш эффект будет применяться к конкретному дочернему
Collapse
компоненту с этим идентификатором.4. Я попробую это. Спасибо.
5. вы должны передать полученные данные на аутсорсинг в компонент и иметь там состояние setopen, чтобы каждый выбранный элемент имел свое собственное состояние … вот как работает поток реакции
Ответ №1:
Создайте отдельный компонент для сохранения состояния «open». Что-то вроде этого..
function QuestionAnswer({post}) {
const [open1, setOpen1] = useState(true);
return (
<>
<div
className="questionrectangle "
onClick={() => setOpen1(!open1)}
name="step-one"
aria-controls="example-collapse-text"
aria-expanded={open1}
>
<p className="questiontext "> {post.QString}</p>
</div>
{open1 amp;amp; (
<div name="step-two">
<p className="questionanswer">{post.Answer}</p>
</div>
)}
</>
);
}
Теперь из вашего основного приложения извлеките данные и создайте один компонент для каждого сообщения — вот так
// Replace this with fetch request
const data = [
{ QString: "Question 1", Answer: "answer 1" },
{ QString: "Question 2", Answer: "answer 2" },
{ QString: "Question 3", Answer: "answer 3" }
];
return (
<Container fluid={true} className="text-center">
{data.map((post) => (
<QuestionAnswer post={post} />
))}
</Container>
);
}
Теперь каждый компонент будет содержать свою собственную копию «открытого» состояния и сможет обрабатывать отдельные открытые и закрытые состояния.
Вы можете увидеть полный образец
Ответ №2:
Хитрость в том, чтобы думать об этом, заключается в том, что каждый дочерний элемент (ваш список <Containers /> ) не должен отвечать за знание о своих братьях и сестрах или о том, как ответственно управлять открытым состоянием между ними, не вызывая конфликтов. Эта ответственность должна быть на один уровень выше, что-то, что может видеть всех дочерних элементов и управлять ими для них.
Должно быть легко принять этот пример аккордеона для вашего собственного использования.
const DocsManager = () => {
// Manage which step is open here, at a higher level
const [openIndex, setOpenIndex] = useState(0); // or whatever the default should be
// Records could live here, or be passed in as props
const [docs, setDocs] = useState([]);
useEffect(() => {
getDocs.then(setDocs);
}, [])
return docs.map((doc, i) =>
<YourComponent
isOpen={openIndex === i}
// Or maybe
open={() => setOpenIndex(i)}
// Or maybe
close={() => setOpenIndex(null)}
// Or maybe
next={() => setOpenIndex(openIndex 1)}
doc={doc}
/>
);
};