Reactjs 是否仅对组件进行react hooks useEffect()清理将卸载?
让我解释一下这段代码的结果,以便轻松地询问我的问题Reactjs 是否仅对组件进行react hooks useEffect()清理将卸载?,reactjs,react-hooks,Reactjs,React Hooks,让我解释一下这段代码的结果,以便轻松地询问我的问题 const ForExample = () => { const [name, setName] = useState(''); const [username, setUsername] = useState(''); useEffect(() => { console.log('effect'); console.log({ name,
const ForExample = () => {
const [name, setName] = useState('');
const [username, setUsername] = useState('');
useEffect(() => {
console.log('effect');
console.log({
name,
username
});
return () => {
console.log('cleaned up');
console.log({
name,
username
});
};
}, [username]);
const handleName = e => {
const { value } = e.target;
setName(value);
};
const handleUsername = e => {
const { value } = e.target;
setUsername(value);
};
return (
<div>
<div>
<input value={name} onChange={handleName} />
<input value={username} onChange={handleUsername} />
</div>
<div>
<div>
<span>{name}</span>
</div>
<div>
<span>{username}</span>
</div>
</div>
</div>
);
};
constexample=()=>{
const[name,setName]=useState(“”);
const[username,setUsername]=useState(“”);
useffect(()=>{
console.log(“效果”);
console.log({
名称
用户名
});
return()=>{
console.log(“已清理”);
console.log({
名称
用户名
});
};
},[用户名];
常量handleName=e=>{
const{value}=e.target;
设置名称(值);
};
常量handleUsername=e=>{
const{value}=e.target;
setUsername(值);
};
返回(
{name}
{username}
);
};
当示例组件装载时,将记录“效果”。这与组件didmount()
有关
每当我更改名称输入时,“效果”和“清理”都将被记录。反之亦然,由于我在useffect()
的第二个参数中添加了[username]
,因此每次更改用户名输入时都不会记录任何消息。这与componentDidUpdate()
最后,当示例组件
卸载时,将记录“已清理”。这与组件willunmount()
有关
我们都知道这一点
总之,只要组件被重新呈现(包括卸载),就会调用“cleanup”
如果我想让这个组件只在卸载时记录“清理”,我只需要将useffect()
的第二个参数更改为[]
但是,如果我将[username]
更改为[]
,例如,对于名称输入,组件不再实现组件diddupdate()
我想做的是,使组件同时支持componentdiddupdate()
仅用于名称输入和componentWillUnmount()
。(仅在卸载组件时记录“已清理”)由于清理不依赖于用户名
,因此可以将清理放在一个单独的useffect
中,并将空数组作为第二个参数
示例
const{useState,useffect}=React;
常量示例=()=>{
const[name,setName]=useState(“”);
const[username,setUsername]=useState(“”);
使用效果(
() => {
控制台日志(“效果”);
},
[用户名]
);
useffect(()=>{
return()=>{
控制台日志(“已清理”);
};
}, []);
常量handleName=e=>{
const{value}=e.target;
设置名称(值);
};
常量handleUsername=e=>{
const{value}=e.target;
setUsername(值);
};
返回(
{name}
{username}
);
};
函数App(){
const[shouldRender,setShouldRender]=useState(true);
useffect(()=>{
设置超时(()=>{
setShouldRender(假);
}, 5000);
}, []);
返回shouldRender?:空;
}
render(,document.getElementById(“根”))代码>
您可以使用多个useEffect
例如,如果我的变量是data1,我可以在我的组件中使用所有这些
useEffect( () => console.log("mount"), [] );
useEffect( () => console.log("will update data1"), [ data1 ] );
useEffect( () => console.log("will update any") );
useEffect( () => () => console.log("will update data1 or unmount"), [ data1 ] );
useEffect( () => () => console.log("unmount"), [] );
功能LegoComponent(){
const[lego,setLegos]=React.useState([])
React.useffect(()=>{
让isSubscribed=true
fetchLegos()。然后(legos=>{
如果(已订阅){
setLegos(乐高积木)
}
})
return()=>isSubscribed=false
}, []);
返回(
{legos.map(lego=>- {lego}
)}
)
}
在上面的代码中,fetchLegos函数返回一个承诺。我们可以通过在useEffect范围内设置条件来“取消”承诺,防止应用程序在卸载组件后设置状态
警告:无法对已卸载的组件执行React状态更新。
这是一个no-op,但它表示应用程序中存在内存泄漏。
要修复此问题,请取消useEffect清理函数中的所有订阅和异步任务
useEffect在其自身范围内被隔离,并相应地进行渲染。
来自
我所做的不是创建太多复杂的函数和方法,而是创建一个事件侦听器,并自动为我完成装载和卸载,而不必担心手动执行。这里有一个例子
//componentDidMount
useEffect( () => {
window.addEventListener("load", pageLoad);
//component will unmount
return () => {
window.removeEventListener("load", pageLoad);
}
});
现在这部分已经完成了,我只需要从pageLoad函数中运行我想要的任何东西,如下所示
const pageLoad = () =>{
console.log(I was mounted and unmounted automatically :D)}
为了补充被接受的答案,我有一个类似的问题,并使用类似的方法解决了它,下面是一个人为的例子。在这种情况下,我需要在组件willunmount
上记录一些参数,正如原始问题中所述,我不希望每次参数更改时都记录这些参数
const componentWillUnmount = useRef(false)
// This is componentWillUnmount
useEffect(() => {
return () => {
componentWillUnmount.current = true
}
}, [])
useEffect(() => {
return () => {
// This line only evaluates to true after the componentWillUnmount happens
if (componentWillUnmount.current) {
console.log(params)
}
}
}, [params]) // This dependency guarantees that when the componentWillUnmount fires it will log the latest params
你可以有两种不同的效果。一个是作为第二个参数提供一个带有username
的数组,另一个是作为第二个参数提供一个空数组。@Thole你的意思是我必须创建两个单独的useEffect()方法吗?是的,这是一种方法。@Thole我想它会被最后一个useEffect()方法覆盖。我试试看。谢谢你!不客气。这取决于清理工作应该做什么。2单独的效果是一个不错的解决方案。first和last useEffects之间有什么区别,first useEffect将在willmount或didmount上调用,last useEffect返回的回调函数为空数组为什么?您能详细说明每个useEffect用例的使用时间和方式吗?@siluverukirankumar返回值(函数)
const componentWillUnmount = useRef(false)
// This is componentWillUnmount
useEffect(() => {
return () => {
componentWillUnmount.current = true
}
}, [])
useEffect(() => {
return () => {
// This line only evaluates to true after the componentWillUnmount happens
if (componentWillUnmount.current) {
console.log(params)
}
}
}, [params]) // This dependency guarantees that when the componentWillUnmount fires it will log the latest params