gpt4 book ai didi

reactjs - 根据父状态 react 功能组件更新子状态

转载 作者:行者123 更新时间:2023-12-04 13:12:12 24 4
gpt4 key购买 nike

假设我们有一个组件 Accordion,其内部状态为 isOpen,因此您可以关闭和打开该组件。
我们现在想要一个父组件,它也有一个状态 isOpen 和一个按钮。在这个组件中,我们有 2 次 Accordion,我们将传递给 Accordion isOpen,我们希望如果父级更改状态 isOpen Accordion 接受这个。
所有组件都是功能组件

 const Accordion = ({ isOpen: parentIsOpen = false }) => {
const [isOpen, setIsOpen] = useState(parentIsOpen);
const handleSetIsOpen = () => setIsOpen(!isOpen);
return (
<div>
I'm open: {isOpen}
<button onClick={handleSetIsOpen}>toggle isOpen child</button>
</div>
);
};

const MasterComponent = () => {
const [isOpen, setIsOpen] = useState(false);
const handleSetIsOpen = () => setIsOpen(!isOpen);
return (
<div>
<button onClick={handleSetIsOpen}>toggle isOpen parent</button>
<Accordion isOpen={isOpen} />
<Accordion isOpen={isOpen} />
</div>
);
};
在这种情况下,上面的 Accordion 将首先呈现为初始状态父 isOpen Prop 。如果我们按下按钮切换 isOpen parent,我们将更改父状态,但不会更新子级。
为了解决这个问题,我们可以使用 useEffect
  const Accordion = ({ isOpen: parentIsOpen = false }) => {
const [isOpen, setIsOpen] = useState(parentIsOpen);
const handleSetIsOpen = () => setIsOpen(!isOpen);

useEffect(() => {
if (parentIsOpen !== isOpen) {
setIsOpen(parentIsOpen);
}
}, [parentIsOpen]);

return (
<div>
I'm open: {isOpen}
<button onClick={handleSetIsOpen}>toggle isOpen child</button>
</div>
);
};

const MasterComponent = () => {
const [isOpen, setIsOpen] = useState(false);
const handleSetIsOpen = () => setIsOpen(!isOpen);
return (
<div>
<button onClick={handleSetIsOpen}>toggle isOpen parent</button>
<Accordion isOpen={isOpen} />
<Accordion isOpen={isOpen} />
</div>
);
};
在这种情况下,当父级更改 isOpen 状态时,子级将被正确更新。
这有一个问题:
“React Hook useEffect 缺少依赖项:'isOpen'。要么包含它,要么删除依赖项数组 react-hooks/exhaustive-deps”
那么如何消除 esLint 提示的这个问题,我们不想把 isOpen 放在里面,因为它会导致错误。
如果我们像这样将 isOpen 添加到数组中:
 useEffect(() => {
if (parentIsOpen !== isOpen) {
setIsOpen(parentIsOpen);
}
}, [parentIsOpen, isOpen]);
然后我们会遇到这样一种情况,我们将单击 Accordion 中的内部按钮并更新内部状态,然后 useEffect 将运行并看到父级与子级的状态不同,并立即设置旧状态。
所以基本上你有一个循环, Accordion 永远不会打开。
问题是根据父状态更新子状态的最佳方法是什么?
请不要建议将所有状态放在父状态并传递没有子状态的 Prop 。这将不起作用,因为本示例中的两个 Accordion 都必须有自己的状态,并且能够以独立的方式打开和关闭,但是如果 parent 说关闭或打开它应该听。
谢谢!

最佳答案

其实我会说这是这样做的方式

 const Accordion = ({ isOpen: parentIsOpen = false }) => {
const [isOpen, setIsOpen] = useState(parentIsOpen);
const handleSetIsOpen = () => setIsOpen(!isOpen);

useEffect(() => {
setIsOpen(parentIsOpen);
}, [parentIsOpen]);

return (
<div>
I'm open: {isOpen}
<button onClick={handleSetIsOpen}>toggle isOpen child</button>
</div>
);
};

const MasterComponent = () => {
const [isOpen, setIsOpen] = useState(false);
const handleSetIsOpen = () => setIsOpen(!isOpen);
return (
<div>
<button onClick={handleSetIsOpen}>toggle isOpen parent</button>
<Accordion isOpen={isOpen} />
<Accordion isOpen={isOpen} />
</div>
);
};
因此,只需删除子组件中的状态检查,让他更新状态,但由于使用相同的值更新,因此不会重新渲染或执行一些昂贵的行为。
今天对其进行了测试并检查,如果状态不同或没有相同,如果更新的状态与以前相同,react 会注意不触发重新渲染。

关于reactjs - 根据父状态 react 功能组件更新子状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64069751/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com