如何在 React 中使用 useState 或条件渲染来隐藏和显示组件?
How do I hide and show components with useState or conditional rendering in React?
我最初要解决的目标:
- 我有 4 个组件并排排列。我希望能够 toggle/onClick 其中一个组件并让其他 3 个组件消失。然后重新切换同一组件以使其他组件重新出现。但也有能力通过切换任何其他组件来完成相同的任务。
- 简单来说,每个组件都是一个 div 标签,其中包含一个图像标签。
我对这个问题的初步看法:
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.log(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),设置chosenNumber,如果我点击的div和chosen一样,就把chosen归零。
每次chosenNumber变化,useEffect都检测到并用chosenNumber过滤数组,如果chose为0,重置stateArray。
现在当我点击其中一个组件时,它们都消失了。我只是不确定使用零来比较每个对象是否正确,或者我需要使用什么来代替。
感谢您的帮助!
一种简单的方法是在 useState 或 mobx 等中将布尔值保存在状态(例如 isVisible = true )中。然后在反应组件中,您可以使用双符号,如下所示:
{isVisible && <MyComponent/>}
这只会在 isVisible = true 时显示
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/>};
如果我是你,我会简化事情。首先,我将从组件中提取 array
,因为您不希望每次重新渲染组件时都重新渲染它。然后,我将更改您的状态并仅保留将包含 array
项的 items
状态。我还会通过提供标志 isVisible
来扩展 array
项。然后,我将删除您的 useEffect
并改进 handleClick
,因为您只想在单击按钮时触发它。在 handleClick
函数中,我将通过映射您的 items
并将“未点击”项目 isVisible
更改为 false 来创建一组新项目。这样,您就知道要隐藏哪些项目。最后,我将根据 isVisible
属性渲染组件。因此,如果 isVisible
为真,则项目将在 hidden
设置为 false
的情况下呈现,反之亦然。
这样代码更简单、更高效、更容易理解。另外,它会按照您的要求进行操作。
这是示例工作代码的 link:codesandbox
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;
我最初要解决的目标:
- 我有 4 个组件并排排列。我希望能够 toggle/onClick 其中一个组件并让其他 3 个组件消失。然后重新切换同一组件以使其他组件重新出现。但也有能力通过切换任何其他组件来完成相同的任务。
- 简单来说,每个组件都是一个 div 标签,其中包含一个图像标签。
我对这个问题的初步看法:
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.log(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),设置chosenNumber,如果我点击的div和chosen一样,就把chosen归零。
每次chosenNumber变化,useEffect都检测到并用chosenNumber过滤数组,如果chose为0,重置stateArray。
现在当我点击其中一个组件时,它们都消失了。我只是不确定使用零来比较每个对象是否正确,或者我需要使用什么来代替。
感谢您的帮助!
一种简单的方法是在 useState 或 mobx 等中将布尔值保存在状态(例如 isVisible = true )中。然后在反应组件中,您可以使用双符号,如下所示:
{isVisible && <MyComponent/>}
这只会在 isVisible = true 时显示
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/>};
如果我是你,我会简化事情。首先,我将从组件中提取 array
,因为您不希望每次重新渲染组件时都重新渲染它。然后,我将更改您的状态并仅保留将包含 array
项的 items
状态。我还会通过提供标志 isVisible
来扩展 array
项。然后,我将删除您的 useEffect
并改进 handleClick
,因为您只想在单击按钮时触发它。在 handleClick
函数中,我将通过映射您的 items
并将“未点击”项目 isVisible
更改为 false 来创建一组新项目。这样,您就知道要隐藏哪些项目。最后,我将根据 isVisible
属性渲染组件。因此,如果 isVisible
为真,则项目将在 hidden
设置为 false
的情况下呈现,反之亦然。
这样代码更简单、更高效、更容易理解。另外,它会按照您的要求进行操作。
这是示例工作代码的 link:codesandbox
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;