Первоначальная цель:
const array = [
{ id: 1, component: <Comp1/>, isVisible: true,
info: [{ id: 5, component: <div>info1</div>, isVisibleInfo: false }] },
{ id: 2, component: <Comp2/>, isVisible: true,
info: [{ id: 6, component: <div>info2</div>, isVisibleInfo: false }] },
{ id: 3, component: <Comp3/>, isVisible: true,
info: [{ id: 7, component: <div>info3</div>, isVisibleInfo: false }] },
{ id: 4, component: <Comp4/>, isVisible: true,
info: [{ id: 8, component: <div>info4</div>, isVisibleInfo: false }] }
];
export const Test = () => {
const [items, setItems] = useState(array);
const handleClick = (number) => {
const triggeredItems = items.map((item) => {
if (item.id !== number) {
item.isVisible = !item.isVisible;
}
return item;
});
setItems(triggeredItems);
};
const handleClickInner = (number) => {
const triggeredItemsInner = items.info.map((item) => {
if (item.id !== number) {
item.isVisibleInfo = !item.isVisibleInfo;
}
return item;
});
setItems(triggeredItemsInner);
};
return (
<div className = "mt-1 pt-1 pb-3 px-3">
<div className = "row text-center d-flex my-1">
{items.map(({ id, component, isVisible, info }) => (
<div
key = {id}
className = "col-lg-3 col-md-6 mb-4 justify-content-center"
onClick = {() => handleClick(id)}
hidden = {!isVisible}
>
{ component }
{info.map(({ id, component, isVisibleInfo }) => (
<div
key = {id}
className = "col-lg-9 col-md-6 mb-4 justify-content-center"
onClick = {() => { handleClickInner(id)}}
hidden = {isVisibleInfo}
>
{ component }
</div>
))}
</div>
))}
</div>
</div>
);
};
export default Test;
На данный момент я получаю этот вывод TypeError: Не удается прочитать карту свойства undefined в функции «handleClickInner», потому что я считаю, что карта не может отображать вложенный массив, но в целом я не уверен, что создание этой второй функции является правильным подходом даже.
Все еще многому учусь о React и его методах!
Любые мысли или помощь будут оценены!
@ Jayce444 Хорошо, понятно, спасибо за информацию. Я не уверен, что создание второй функции для отображения, как у меня сейчас, является правильным способом достижения того, чего я хочу достичь, это был мой первоначальный мыслительный процесс.
Я бы сделал именно то, о чем ты думаешь... звучит как реакция на меня.
Моя цель - добавить объект информации/описания к каждому из компонентов. в массиве, чтобы при переключении компонента другие компоненты по-прежнему исчезают, но теперь появляется описание в соответствии с переключаемый компонент.
Ты действительно имеешь в виду исчезнуть, не так ли? больше похоже на то, что вы хотите условно визуализировать компонент.
ОБНОВЛЕНО
Я неправильно понял ваши намерения! Теперь они исчезают.
// hooks
const {useState} = React;
function Comp1(){
return <div><p>Component 1</p></div>
}
function Comp2(){
return <div><p>Component 2</p></div>
}
function Comp3(){
return <div><p>Component 3</p></div>
}
function Comp4(){
return <div><p>Component 4</p></div>
}
const array = [
{ id: 1, component: <Comp1/>, isVisible: true,
info: { id: 5, component: <div>info1</div>, isVisibleInfo: false } },
{ id: 2, component: <Comp2/>, isVisible: true,
info: { id: 6, component: <div>info2</div>, isVisibleInfo: false } },
{ id: 3, component: <Comp3/>, isVisible: true,
info: { id: 7, component: <div>info3</div>, isVisibleInfo: false } },
{ id: 4, component: <Comp4/>, isVisible: true,
info: { id: 8, component: <div>info4</div>, isVisibleInfo: false } }
];
const Test = () => {
const [items, setItems] = useState(array);
const handleClick = (number) => {
const triggeredItems = items.map((item) => {
if (item.id !== number) {
item.isVisible = !item.isVisible;
}
item.info.isVisibleInfo =! item.info.isVisibleInfo
return item;
});
setItems(triggeredItems);
};
return (
<div className = "mt-1 pt-1 pb-3 px-3">
<div className = "row text-center d-flex my-1">
{items.map(({ id, component, isVisible, info }) => (
isVisible ?
<div
key = {id}
className = "col-lg-3 col-md-6 mb-4 justify-content-center"
onClick = {() => handleClick(id)}
hidden = {!isVisible}
>
{ component }
{info.isVisibleInfo ?
<div
key = {info.id}
className = "col-lg-9 col-md-6 mb-4 justify-content-center"
>
{ info.component }
</div>
: null}
</div>
: null
))}
</div>
</div>
);
};
function App(){
return (
<div>
<Test />
</div>
);
};
// Render
ReactDOM.render(
<App />,
document.getElementById("react")
);
<div id = "react"></div>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
Да, я считаю, что условно рендерить — это правильная терминология. Я проверил ваш код, и на выходе я получаю 3 тега div Info, которые не соответствуют компоненту, на который нажимают, ха-ха. Например, если я нажму <comp1/>, вывод будет "info2, info3, info4". Вместо просто «info1». Это проблема с моей функцией handleClick?
Нет, я думал, это и есть твоя цель ^_^. Я обновлю код.
Как раз то, что мне было нужно! Просто из любопытства, возможно ли, чтобы информационный объект находился в собственном теге div за пределами тега div Comp1, например?
Компонент может отображать только один div <div><p>hi</p><p>there</p></div>
это хорошо, но не <div>1</div><div>2</div>
В этом есть смысл. Я просто подумал, что если бы я обернул <div>1</div><div>2<div/>
внешним div, чтобы он выглядел так: <div> <div>1</div><div>2<div/> </div>
. Тогда я предполагаю, что <div>1</div>
и <div>2</div>
будут действовать как отдельные элементы внутри внешнего тега. Однако, когда я проверяю это, кажется, что <div>2</div>
все еще действует как дочерний элемент для <div>1</div>
. Это просто так? Просто смущен этим.
Вы можете сделать это. Подумайте об этом так; компонент должен иметь контейнер div. Так что можно <div className='container'><div>inner 1</div><div>inner2</div></div>
items
— это не объект,items
— это массив объектов. Итак,items.info
не определено. Вам нужно будет получить доступ к определенному объекту, чтобы изменить его информационный массив, например.items[0].info.map