繁体   English   中英

如何在 React 中隐藏和显示带有 useState 或条件渲染的组件?

[英]How do I hide and show components with useState or conditional rendering in React?

我最初要解决的目标:

  • 我有 4 个组件并排排列在一起。 我希望能够切换/单击其中一个组件并让其他 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)时,我将设置choiceNumber,如果我点击的div与选择的相同,则将选择重置为零。

每次 selectedNumber 变化时,useEffect 都应该检测到它并使用 selectedNumber 过滤数组,如果选择为零,则重置 stateArray。

现在,当我单击其中一个组件时,它们都消失了。 我只是不确定使用零是否适合用于比较每个 object 或我需要使用的东西。

谢谢您的帮助!

如果我是你,我会简化事情。 首先,我会从组件中提取array ,因为您不希望每次重新渲染组件时都重新渲染它。 然后,我将更改您的 state 并仅保留将包含array项的items state。 我还将通过提供标志isVisible来扩展array项。 然后,我将删除您的useEffect并改进handleClick ,因为您只想在单击按钮时触发它。 handleClick function 中,我将通过映射您的items并将“未点击”项目的isVisible更改为 false 来创建一组新项目。 这样,您就知道要隐藏哪些项目。 最后,我将根据isVisible属性呈现组件。 因此,如果isVisible为 true,则该项目将在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;

一种简单的方法是在 useState 或 mobx 等中将 boolean 保存在 state 中(例如 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/>};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM