Joh*_*_ny 17 javascript reactjs react-redux react-hooks
我试图深入了解useEffect钩子。
我想知道何时使用哪种方法以及为什么?
1.useEffect with no second paraments
useEffect(()=>{})
2.useEffect with second paraments as []
useEffect(()=>{},[])
3.useEffect with some arguments passed in the second parameter
useEffect(()=>{},[arg])
Run Code Online (Sandbox Code Playgroud)
Den*_*ash 32
useEffect(callback);
// Example
useEffect(() => {
console.log("executed after render phase");
return () => {
console.log("cleanup function after render");
};
});
Run Code Online (Sandbox Code Playgroud)
const Component = () => {
callback()
return <></>;
};
Run Code Online (Sandbox Code Playgroud)
Note: There is still a difference, in execution time (see the next note). Check this sandbox logs.
useEffect(callback,[]);
// Example
useEffect(() => {
const fetchUsers = async () => {
const users = await fetch();
setUsers(users);
};
fetchUsers();
console.log("called on component's mount");
return () => {
console.log("called on component's unmount");
};
}, []);
Run Code Online (Sandbox Code Playgroud)
Gotchas:
Remember, there is a first render and then a mount.
Roughly saying, most of bugs regarding
useEffectis not knowing how closures works and not paying attention to linting warnings.
Make sure the array includes all values from the component scope that change over time and that are used by the effect. Otherwise, your code will reference stale values from previous renders - note in React docs.
useEffect(callback,[arg]);
// Example
useEffect(() => {
console.log({ users });
return () => {
console.log("user value is changing");
};
}, [users]);
Run Code Online (Sandbox Code Playgroud)
arg value.[arg1,arg2,arg3...]arg value change.Gotchas:
arg.i.e compares the value of
argfrom the previous render and the current one,prevArg === arg ? doNothing() : callback().
{} === {} || [] === [] is a falsy statement, if arg (users in our example) is an object, the callback will run on every render.useEffect callbacks fired after browser's re-paint.useEffect callbacks executed in declaration order (like all hooks), check the example.useEffect should have a SINGLE responsibility.useRef, in the cleanup function, copy the value to callback's scope beforehand.const timeoutIdRef = useRef();
useEffect(() => {
const timeoutId = timeoutIdRef.current;
return () => {
/*
Using timeoutIdRef.current directly here is not safe
since you can't guarantee the ref to exists in this point
(especially when the component unmounts)
*/
// Should get a lint warning here
clearTimeout(timeoutIdRef.current); // BAD
// Closure on timeoutId value
clearTimeout(timeoutId); // GOOD
};
}, [arg]);
Run Code Online (Sandbox Code Playgroud)
ref.current as useEffect's dependency when ref points to a DOM element?useEffect ONCE, on mount or on first render, those are the common patterns.const isMounted = useRef(false);
useEffect(() => {
if (isMounted.current) {
// first mount
} else {
isMounted.current = true;
}
}, [arg]);
Run Code Online (Sandbox Code Playgroud)
Keep reading:
return statement of useEffect callbackuseEffect by Dan AbramovuseEffect API| 归档时间: |
|
| 查看次数: |
2979 次 |
| 最近记录: |