Reactjs 在子对象之前卸载父对象
几个月以来我一直在做react。我从几天开始使用钩子(我知道得很晚),事情是,与生命周期方法相比,它们在某些方面看起来是不同的 useEffect挂钩可以复制:Reactjs 在子对象之前卸载父对象,reactjs,react-hooks,Reactjs,React Hooks,几个月以来我一直在做react。我从几天开始使用钩子(我知道得很晚),事情是,与生命周期方法相比,它们在某些方面看起来是不同的 useEffect挂钩可以复制: -componentDidMount(); -componentDidUpdate(); -componentWillUnMount(); 但我观察到react的组件和函数之间的差异,这与函数的卸载方式有关。我注意到了unmount方法,与react的组件相比,react的函数在子/ren之前卸载父级 import React, {
-componentDidMount();
-componentDidUpdate();
-componentWillUnMount();
但我观察到react的组件和函数之间的差异,这与函数的卸载方式有关。我注意到了unmount方法,与react的组件相比,react的函数在子/ren之前卸载父级
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>
);
}
从“React”导入React,{ReactElement,useffect,useState};
从“react router dom”导入{useLocation,useHistory};
导出函数Child2({
计数
未安装的儿童,
}: {
计数:数字;
未安装的儿童:功能;
}):反应元件{
useffect(()=>{
return()=>{
console.log(“卸载”);
未安装的儿童(计数);
};
},[计数];
返回(
不为所动
);
}
导出函数Child1({count}:{count:number}):ReactElement{
const[validation,setValidation]=useState(false);
const usehistory=usehistory();
const childrenUnmounted=(计数:数字)=>{
日志(“验证”、验证、计数);
设置验证(假);
};
常量changeUrl=()=>{
设置验证(真);
usehistory.push(“http://localhost:3000/${count}”);
};
返回(
递增
childrenUnmounted(计数)}
/>
changeUrl()}>
验证
使用history.push(`http://localhost:3000/${count}`)}
>
不
);
}
导出默认函数父级():ReactElement{
const[count,setcount]=useState(-1);
const location=useLocation();
useffect(()=>{
设置计数(计数+1);
},[地点];
返回(
你好
{count}
);
}
当你点击validation
按钮时,上面的代码会发生一些恼人的事情。单击时,Child1
中的值为true
,更改URL
可触发父项的重新加载程序以更改数据(此处为计数)
我不明白的是,为什么在卸载Child2时,在调用Child1中的childrenUnmounted(count)(触发相同的函数,但在Child1中)时,即使单击了验证,验证也等于false
?当你在验证后点击nope
时,你得到了正确的答案。。。看起来孩子1不在乎验证的当前状态(他使用以前的状态)
有人能帮我了解发生了什么事吗?
谢谢你的帮助
解决方案: 我在验证中使用了useRef而不是useState,以避免重新渲染,因为Giovanni Esposito说: 因为钩子是异步的,您无法获取为state设置的最后一个值
所以useRef是我的解决方案Ciao,我认为您的问题与记录
验证
值时的有关。我解释得更好
您的父母关系是:父母->子女1->子女2。嗯
现在您单击Child2上的验证按钮<代码>验证
按钮调用调用changeUrl
的调用usehistory.push(“http://localhost:3000/${count}”)代码>和开始更改验证
值(为什么会启动?因为设置验证
是异步的)
如果现在卸载Child2,则可能是asyncsetValidation
尚未设置validation
(日志返回validation
的旧值)
嗯,在某个时刻,这个setValidation
完成并将validation
设置为true。现在,单击nope
按钮,您将获得验证的true(设置的最后一个值)
因此,简而言之,我认为您在日志中看到的只是因为钩子是异步的,并且您无法获得为state设置的最后一个值(如果您以这种方式使用日志)。您必须始终记录最后一个设置的值的唯一方法是useffect
hook,其中包含您要在deps列表中登录的值。是的,您说得对!至少我找到了解决这个问题的办法。如果我在验证中使用useRef而不是useState,我可以直接使用该值,因为useRef不需要重新渲染来修改该值;)听到这个消息我很高兴。如果您认为此答案有用,请标记为有效。祝你今天愉快:)