挂钩父母在孩子之前卸下
Posted
技术标签:
【中文标题】挂钩父母在孩子之前卸下【英文标题】:Hooks parent unmounted before children 【发布时间】:2020-08-13 07:58:03 【问题描述】:几个月以来,我一直致力于做出反应。我从几天开始就开始使用 Hooks(我知道很晚了),问题是,与 React 组件相比,生命周期方法看起来在某些方面有所不同。
useEffect 钩子可以重现:
-componentDidMount();
-componentDidUpdate();
-componentWillUnMount();
但我观察到 react 的组件和函数之间的区别在于卸载函数的方式。我注意到了卸载方法,与反应的组件相比,反应的功能在子/人之前卸载父
import React, ReactElement, useEffect, useState from "react";
import useLocation, useHistory from "react-router-dom";
export function Child2(
count,
childrenUnmounted,
:
count: number;
childrenUnmounted: Function;
): ReactElement
useEffect(() =>
return () =>
console.log("Unmounted");
childrenUnmounted(count);
;
, [, count]);
return (
<div>
<h2>Unmouted</h2>
</div>
);
export function Child1( count : count: number ): ReactElement
const [validation, setValidation] = useState(false);
const usehistory = useHistory();
const childrenUnmounted = (count: number) =>
console.log("validation", validation, count);
setValidation(false);
;
const changeUrl = () =>
setValidation(true);
usehistory.push("http://localhost:3000/$count");
;
return (
<div>
<h2>incremente</h2>
<Child2
count=count
childrenUnmounted=(count: number) => childrenUnmounted(count)
/>
<button className="button" onClick=() => changeUrl()>
validation
</button>
<button
className="button"
onClick=() => usehistory.push(`http://localhost:3000/$count`)
>
nope
</button>
</div>
);
export default function Parent(): ReactElement
const [count, setcount] = useState(-1);
const location = useLocation();
useEffect(() =>
setcount(count + 1);
, [, location]);
return (
<div>
<h2>hello</h2>
<h3>count</h3>
<Child1 count=count />
</div>
);
当您单击validation
按钮时,上面的代码会发生一些烦人的事情。 Child1
中的值是true
,在点击的那一刻,它改变了URL
来触发重新渲染Parent
来改变数据(这里是计数)。
我不明白的是为什么在 Child1 中卸载 Child2 时,在 Child1 中调用的 childrenUnmounted(count)(触发相同的函数但在 Child1 中)验证等于 false
,甚至点击验证?当您在验证后单击nope
时,您得到了真实...看起来 Child1 与validation
的当前状态无关(他使用以前的状态)
有人可以帮助我了解发生了什么吗? 感谢您的帮助。
解决方案:
我在验证中使用了 useRef 而不是 useState 以不依赖于重新渲染,正如 Giovanni Esposito
所说:
因为钩子是异步的,您无法获得为状态设置的最后一个值
所以 useRef 是我的解决方案
【问题讨论】:
【参考方案1】:Ciao,我认为您的问题与何时您记录validation
值有关。我解释得更好。
您的父母关系是:父母 -> Child1 -> Child2。好的。
现在您单击 Child2 上的 validation
按钮。 validation
按钮调用 changeUrl
调用 usehistory.push("http://localhost:3000/$count");
并且开始更改 validation
值(为什么要开始?因为 setValidation
是异步的)。
如果 Child2 现在卸载,可能是 validation
的值尚未由 async setValidation
设置(并且日志返回 validation
的旧值)。
好吧,在某个时候,setValidation
完成并将 validation
设置为 true。现在点击nope
按钮,validation
(最后设置的值)为 true。
所以,简而言之,我认为您在日志中看到的只是因为钩子是异步的,并且您无法获得为状态设置的最后一个值(如果您以这种方式使用日志)。您必须始终记录最后设置的值的唯一方法是 useEffect
挂钩,其中包含您要登录 deps 列表的值。
【讨论】:
是的,你说得对!至少我找到了解决这个问题的方法。如果我在验证中使用 useRef 而不是 useState ,我可以直接使用该值,因为 useRef 不需要重新渲染来修改该值;)thx 很高兴听到这个消息。如果您发现此答案有用,请标记为有效。祝你有美好的一天:)以上是关于挂钩父母在孩子之前卸下的主要内容,如果未能解决你的问题,请参考以下文章
收到错误“指定的孩子已经有父母。您必须先在孩子的父母上调用 removeView()。”? [复制]