如何在 React 中隐藏和显示带有 useState 或条件渲染的组件?
Posted
技术标签:
【中文标题】如何在 React 中隐藏和显示带有 useState 或条件渲染的组件?【英文标题】:How do I hide and show components with useState or conditional rendering in React? 【发布时间】:2021-03-22 02:47:22 【问题描述】:我最初要解决的目标:
我有 4 个组件并排排列在一起。我希望能够切换/单击其中一个组件并让其他 3 个组件消失。然后重新切换相同的组件以使其他组件重新出现。但也有能力通过切换任何其他组件来完成相同的任务。 每个组件简单来说就是一个div标签,里面有一个image标签。我对这个问题的初步看法:
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)时,我会设置choiceNumber,如果我点击的div与选择的div相同,则将选择重置为零。
每次 selectedNumber 发生变化时,useEffect 都会检测到并使用 selectedNumber 过滤数组,如果选择为零,则重置 stateArray。
现在,当我单击其中一个组件时,它们都消失了。我只是不确定使用零是比较每个对象的正确方法还是我需要使用的方法。
感谢您的帮助!
【问题讨论】:
到目前为止你尝试了什么? 如果您想获得帮助,请告诉我们您至少尝试通过提供代码 sn-ps 以及您可能遇到的问题自己解决它。我们不会为您解决此问题,但如果您尝试,我们会为您提供帮助。 @MantasAstra 我刚刚更新了我的问题。对于我最初写问题的方式,我深表歉意 @clod9353 我更新了我的问题。希望这是一种更好的格式。对于开头的措辞,我深表歉意。 【参考方案1】:如果我是你,我会简化事情。首先,我会从组件中提取array
,因为您不希望每次重新渲染组件时都重新渲染它。然后,我将更改您的状态并仅保留包含 array
项目的 items
状态。我还将通过提供标志isVisible
来扩展array
项目。然后,我会删除您的useEffect
并改进handleClick
,因为您只想在单击按钮时触发它。在handleClick
函数中,我将通过映射您的items
并将“未点击”项目isVisible
更改为false 来创建一组新项目。这样,您就知道要隐藏哪些项目。最后,我将根据isVisible
属性呈现组件。因此,如果isVisible
为真,则该项目将在呈现时将hidden
设置为false
,反之亦然。
这样代码更简单,性能更高,更容易理解。另外,它可以满足您的要求。
这是示例工作代码的链接: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;
【讨论】:
感谢您的示例和建议。对此,我真的非常感激。目前,这会打印出每个组件的 id,但理想情况下希望与 id 对应的 div 标签是要打印的内容。我了解 map 函数将 id 作为索引来索引数组,但我希望 div 是切换可见或不可见的内容。有什么想法吗? 您仍然可以应用相同的技术,只要您将组件包装在div
或其他东西中,以便您可以打开/关闭它。我已经使用包含组件并呈现它们的示例编辑了我的初始答案。 @PatrikKozak
我只需要将“组件”添加到地图功能。再次感谢您的帮助!
我想添加一个与数组中每个特定对象相对应的新对象/元素,例如所述组件的“描述”,我只希望在单击其中一个时显示它们的描述成分。如果我在这个初始数组的每个对象中设置一个包含“描述”信息的数组,我可以在每个对象存在时显示信息,在其他世界中总是“isVisible = true”。但它需要以 false 开始,然后在单击组件时更改为 true,再次单击组件时将其更改回 false。我似乎无法弄清楚那部分。【参考方案2】:
一种简单的方法是在 useState 或 mobx 等中将布尔值保存在 state 中(例如 isVisible = true )。然后在 react 组件中,您可以使用双 & 符号,如下所示:
isVisible && <MyComponent/>
这只会在 isVisible = true 时显示
【讨论】:
感谢您的回复!这也是我最初对该问题的看法,但我在如何更新每个组件的状态方面遇到了困难,即如果组件 1 被切换,则使组件 2-4 不可见(假),然后重复此逻辑其他组件。希望这是有道理的。【参考方案3】: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/>;
【讨论】:
我很欣赏这个例子!我重新更新了我的问题,以包括我对这个问题的初步看法。我尝试使用您的解决方案,但在实施时遇到了一些麻烦。该按钮不执行任何操作,只有第一个组件可见。 对不起!忘记加break;在 switch 语句中每个 case 的末尾。试试看以上是关于如何在 React 中隐藏和显示带有 useState 或条件渲染的组件?的主要内容,如果未能解决你的问题,请参考以下文章