javascript 如何在React中为动态数组Map管理单独的状态变量?

pu3pd22g  于 2023-04-10  发布在  Java
关注(0)|答案(2)|浏览(98)

我正在处理的例子是:我有一个要Map的数组。对于数组的每个索引,一个组件将被显示,然后在x次之后,它将被替换为不同的组件(永久)。

const Parent = ({ array }) => {
  const [isVisible, setIsVisible] = useState(true);

  setTimeout(() => {
    setIsVisible(false);
  }, 1000);

  return array.map((item, index) => {
    return (
      <div key={index}>
        {isVisible && <Child>{item}</Child>}
        {!isVisible && <Child2>{item}</Child2>}
      </div>
    )
  })
}

上面的代码在第一个索引处按预期工作。状态更改后,后面的数组项不会“切换”组件。只有第二个组件被呈现(因为!isVisible为true)。
有没有办法为这个动态数组的每个索引都设置一个状态变量?

8wtpewkr

8wtpewkr1#

你应该在useEffect中执行setTimeout,否则它会运行每个渲染。
为了回答你的问题,是的,你可以把它放在自己的组件中,以简化它的逻辑。这让每个元素管理自己的计时器,而不是父元素管理所有其子元素。这只适用于简单的情况。如果你想要更复杂的东西,例如,每个子元素在最后一个子元素之后一秒可见,父代将需要通过forwardProps或props或广播事件来进行一些管理。

function ChildWrapper(props) {
    const { item } = props;
    const [isVisible, setIsVisible] = useState(true);

    useEffect(() => {
        let isMounted = true;

        setTimeout(() => {
            // Do not call state changes on unmounted components
            if (!isMounted) return;
            setIsVisible(false);
        }, 1000);

        return () => {
            isMounted = false;
        }
    }, []);

    return (
        {isVisible
            ? <Child>{item}</Child>
            : <Child2>{item}</Child2>
        }
    );
}
const Parent = ({ array }) => {
  return array.map((item: any, index: number) => {
    return (
      <div key={index}>
        <ChildWrapper item={item} />
      </div>
    )
  })
}
bmp9r5qi

bmp9r5qi2#

您可以将逻辑提取到单独的组件中。

function ChildWrapper({ item }) {
    const [showFirst, setShowFirst] = useState(true);
    useEffect(() => {
        setTimeout(() => setShowFirst(false), 1000);
    }, []);
    return <div>
        {showFirst ? <Child>{item}</Child> : <Child2>{item}</Child2>}
    </div>;
}

const Parent = ({ array }) => {
    return array.map((item, index) => <ChildWrapper key={index} item={item}/>);
};

工作示例:

function Child({ children }) {
  return 'child 1: ' + children;
}
function Child2({ children }) {
  return 'child 2: ' + children;
}
function ChildWrapper({ item }) {
    const [showFirst, setShowFirst] = React.useState(true);
    React.useEffect(() => {
        setTimeout(() => setShowFirst(false), 1000);
    }, []);
    return <div>
        {showFirst ? <Child>{item}</Child> : <Child2>{item}</Child2>}
    </div>;
}
const Parent = ({ array }) => {
    return array.map((item, index) => <ChildWrapper key={index} item={item}/>);
};
function App() {
  const [arr, setArr] = React.useState(['a', 'b', 'c']);
  return (
    <React.Fragment>
      <Parent array={arr}/>
      <button onClick={() => setArr(arr.concat(Math.random()))}>
        Add
      </button>
    </React.Fragment>
  );
}
ReactDOM.createRoot(document.getElementById('root')).render(<App/>);
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div id="root"></div>

相关问题