Моя первоначальная цель решить:
Мой первоначальный взгляд на проблему:
export const Test = () => {
const intialValue = [{id: 0, component: null}]
const array = [
{id: 1, component: <CompOne/>},
{id: 2, component: <CompTwo/>},
{id: 3, component: <CompThree/>},
{id: 4, component: <CompFour/>}
]
const [chosenNumber, setChosen] = useState(0)
const [statearray, setArray] = useState(array)
useEffect(() => {
console.info(chosenNumber)
const arr = array
if (chosenNumber === 0 ) setArray(array)
else setArray(arr.filter( num => num === chosenNumber))
}, [chosenNumber])
const handleClick = (number) => {
if (number === chosenNumber) setChosen(0)
else setChosen(number)
}
return (
<div className = "flex" >
{statearray.map((comp, number) => <div key = {number} className = "h-12 w-12 bg-gray-400 m-1 flex items-center justify-center" onClick = {() => handleClick(comp.id)}>{comp.id}</div>)}
</div>
);
}
Мой мыслительный процесс заключается в том, что когда я щелкаю компонент (div), я устанавливаю selectedNumber, если div, который я щелкнул, совпадает с выбранным, сбросить выбранное до нуля.
Каждый раз, когда selectedNumber изменяется, useEffect должен обнаружить это и отфильтровать массив с selectedNumber, если selected равен нулю, сбросить stateArray.
Прямо сейчас, когда я нажимаю на один из компонентов, они все исчезают. Я просто не уверен, правильно ли использовать ноль для сравнения каждого объекта или того, что мне нужно использовать вместо этого.
Спасибо за помощь!
Если вы хотите получить помощь, покажите нам, что вы хотя бы пытались решить ее самостоятельно, предоставив фрагменты кода и где вы потенциально застряли. Мы не решим это за вас, но мы поможем вам, если вы попытаетесь.
@MantasAstra Я только что обновил свой вопрос. Я извиняюсь за то, как изначально я написал свой вопрос
@ clod9353 Я обновил свой вопрос. Надеюсь, это лучший формат. Прошу прощения за фразу в начале.
Один из простых способов — сохранить логическое значение в состоянии (например, isVisible = true) либо в useState, либо в mobx и т. д. Затем в компоненте реакции вы можете использовать двойной амперсанд, как показано ниже:
{isVisible && <MyComponent/>}
Это будет отображаться только в том случае, если isVisible = true
Спасибо за ответ! Это был мой первоначальный взгляд на проблему, но у меня были трудности с обновлением состояния каждого компонента в том смысле, что если компонент 1 переключается, сделать компоненты 2-4 невидимыми (false), а затем повторить эту логику для другие компоненты. Надеюсь, это имеет смысл.
const [currentComponent, setCurrentComponent] = useState(1);
const handleClick = () =>{
switch(currentComponent){
case 1:
setCurrentComponent(2)
case 2:
setCurrentComponent(3)
case 3:
setCurrentComponent(4)
case 4:
setCurrentComponent(1)
}
}
<button onClick = {()=> handleClick()}>Click me!</button>
{currentComponent == 1 && <Comp1/>};
{currentComponent == 2 && <Comp2/>};
{currentComponent == 3 && <Comp3/>};
{currentComponent == 4 && <Comp4/>};
Я ценю пример! Я повторно обновил свой вопрос, чтобы включить мой первоначальный подход к проблеме. Я пытался использовать ваше решение, но у меня возникли проблемы с его реализацией. Кнопка ничего не делает, и виден только первый компонент.
Извини! Забыл добавить перерыв; в конце каждого case в операторе switch. Попробуй это
На вашем месте я бы все упростил. Во-первых, я бы извлек array
из компонента, так как вы не хотите, чтобы он повторно отображался каждый раз при повторном отображении компонента. Затем я бы изменил ваше состояние и оставил только состояние items
, которое будет содержать array
элементы. Я бы также расширил элементы array
, добавив флаг isVisible
. Затем я бы удалил ваш useEffect
и улучшил handleClick
, поскольку вы хотите, чтобы это вызывалось только при нажатии кнопки. В функции handleClick
я бы создал новый набор элементов, сопоставив ваш items
и изменив «не нажатые» элементы isVisible
на false. Таким образом, вы знаете, какие предметы нужно спрятать. Наконец, я бы визуализировал компоненты на основе атрибута isVisible
. Таким образом, если isVisible
истинно, элемент будет отображаться с hidden
, установленным на false
, и наоборот.
Таким образом, код становится намного проще, производительнее и понятнее. Кроме того, он делает то, что вы просили.
Вот ссылка на пример рабочего кода: codeandbox
import React, { useState } from "react";
const Comp1 = () => <div>hi</div>;
const Comp2 = () => <div>hi2</div>;
const Comp3 = () => <div>hi3</div>;
const array = [
{ id: 1, component: <Comp1 />, isVisible: true },
{ id: 2, component: <Comp2 />, isVisible: true },
{ id: 3, component: <Comp3 />, isVisible: true }
];
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);
};
return (
<div className = "flex">
{items.map(({ id, component, isVisible }) => (
<div
key = {id}
className = "h-12 w-12 bg-gray-400 m-1 flex items-center justify-center"
onClick = {() => handleClick(id)}
hidden = {!isVisible}
>
{component}
</div>
))}
</div>
);
};
export default Test;
Спасибо за пример и совет. Я очень ценю это. На данный момент это выводит идентификатор каждого компонента, но в идеале нужно, чтобы тег div, соответствующий идентификатору, был тем, что печатается. Я понимаю, что функция карты принимает идентификатор в качестве индекса для индексации массива, но я бы хотел, чтобы div были видимыми или невидимыми. Есть предположения?
Вы по-прежнему можете применять ту же технику, пока вы обертываете компоненты div
или чем-то еще, чтобы вы могли включать и выключать их. Я отредактировал свой первоначальный ответ с примером, который принимает компоненты и отображает их. @PatrikKozak
Мне просто нужно было добавить «компонент» в функцию карты. Еще раз спасибо за помощь!
Я хочу добавить новый объект/элемент в соответствии с каждым конкретным объектом в массиве, например, «описание» указанного компонента, и я хочу, чтобы их описание отображалось только при нажатии на один из компонентов. Если я создаю массив внутри каждого объекта этого исходного массива, который содержит информацию «описание», я могу отображать информацию, когда присутствует каждый объект, в других мирах всегда «isVisible = true». Но он должен начинаться как false, затем при щелчке компонента измениться на true, а при повторном щелчке компонента снова изменить его на false. Я не могу понять эту часть.
что ты уже испробовал?