如何在 React 中使用 useState 或条件渲染来隐藏和显示组件?

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

我最初要解决的目标:

我对这个问题的初步看法:

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;