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