当 props 改变时,组件数组不会更新

Tiw*_*tiw 0 javascript reactjs react-hooks

代码沙盒链接

我有两个组件,一个父组件和一个子组件。父组件将子组件的列表保存在状态中,并使用 map 方法渲染它。

家长:

import { useState } from "react";
import Child from "./Child";

export default function Parent(){
    const [counter, setCounter] = useState(0)
    const [childKey, setChildKey] = useState(0);
    const [children, setChildren] = useState([]);

    function addChild(){
        setChildren([...children, <Child counter={counter} index={childKey}/>]);
        setChildKey(childKey + 1);
    }

    return (
        <>
            <h2>The parent component</h2>
            <p>The counter is set to {counter}</p>
            <p><button onClick={() => {setCounter(counter + 1)}}>Increment</button></p>
            <p><button onClick={addChild}>Add child</button></p>

            {children.map((c, i) => {
                return (
                        <div key={i}>{c}</div>
                    );
            })}
            
        </>
    );
}
Run Code Online (Sandbox Code Playgroud)

孩子:

export default function Child({counter, index}){
    return (
        <>
            <p>Child {index}: the counter is set to {counter}</p>
        </>
    );
}
Run Code Online (Sandbox Code Playgroud)

单击“添加子项”按钮将一个子项添加到子项数组中。

单击“增量”按钮会更新父级中的计数器,但子级中的计数器不会更改。

当计数器增加时,有没有办法重新渲染孩子?(同时最好将孩子们放在一个数组中)

代码沙盒链接

Nic*_*wer 5

setChildren([...children, <Child counter={counter} index={childKey}/>]);
Run Code Online (Sandbox Code Playgroud)

不要将元素放入状态。这使得很容易出现像您现在遇到的那样的错误。您已经有效地“锁定”了孩子的道具是什么,因此对计数器的更改不会生效。

相反,只需存储创建元素所需的最少数据,然后在渲染期间创建这些元素。就你而言,我认为你只需要一个数字来说明要渲染多少个孩子。方便的是,您已经在 中拥有了它childKey,所以我建议:

export default function Parent(){
    const [counter, setCounter] = useState(0)
    const [childKey, setChildKey] = useState(0);

    const children = [];
    for (let i = 1; i <= childKey; i++) {
      children.push((
        <div key={i}>
          <Child counter={counter} index={i} />
        </div>
      ));
    }

    function addChild(){
        setChildKey(childKey + 1);
    }

    return (
        <>
            <h2>The parent component</h2>
            <p>The counter is set to {counter}</p>
            <p><button onClick={() => {setCounter(counter + 1)}}>Increment</button></p>
            <p><button onClick={addChild}>Add child</button></p>

            {children}
            
        </>
    );
}
Run Code Online (Sandbox Code Playgroud)

也许childKey可以重命名为childCount.