In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-10 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)05/31 Report--
This article mainly introduces the relevant knowledge of "how to solve the useEffect closure problem in react". The editor shows you the operation process through an actual case. The operation method is simple, fast and practical. I hope this article "how to solve the useEffect closure problem in react" can help you solve the problem.
Problem code
Look at a closure problem code caused by useEffect
Const btn = useRef (); const [v, setV] = useState (''); useEffect () = > {let clickHandle = () = > {console.log ('v click', clickHandle) return () = > {btn.removeEventListener ('click', clickHandle)}, []) Const inputHandle = e = > {setV (e.target.value)} return (Test)
UseEffect's array of dependencies is empty, so after the page is rendered, the internal code is executed only once, and the page is destroyed and executed again. At this time, enter any character in the input box, and then click the test button, the output is empty, and then no matter how to enter any character, and then click the test button, the output result is still empty.
What causes it? In fact, it is caused by closures.
Cause
The scope of a function is determined when the function is defined.
When registering a click event with btn, the scope is as follows:
The accessible free variable v is still null at this time. When the click event is triggered, the click callback function is executed. At this time, the execution context is first created, and the scope chain is copied to the execution context.
If you do not enter a character in the input box, the v you click to get is the same as the original v
If you type a character in the input box, the setV is called to modify the state, and the page triggers the render. The internal code of the component will be executed again, and the v in the scope of the click event will no longer be the original v. Here, the v in the scope of the click event is still the old v. These are two different v.
Generate a scene
Event binding. For example, in the sample code, the event is bound only once after the initial rendering of the page is completed, such as using echarts to get an instance of echarts in useEffect and bind the event.
Timer. Register a timer after the page is loaded, and the functions in the timer will have the same closure problem.
Solution.
Here are roughly five solutions to this closure problem.
1. Modify v directly by assignment, and wrap the method of modifying v in useCallback
Wrap the method of modifying v in useCallback, and the function wrapped by useCallback will be cached. Because the array of dependencies is empty, the v modified by direct assignment here is the old v. This method is not recommended, because setState is the officially recommended way to modify state, and setV is still used here just to trigger rerender.
The declaration of / / v is changed from const to var, which makes it convenient to directly modify var [v, setV] = useState (''); const inputHandle = useCallback (e = > {let {value} = e.target v = value setV (value)}, [])
two。 Add v to the dependency of useEffect
This may be the first way that most people think of. Since v is old, it is not OK to re-register the event every time v is updated, but this will result in re-registration for every v update. The event that should only be registered once in theory has become multiple times.
3. To prevent v from being restated
Declare a variable instead of v in the way of let or var, and modify the variable directly, instead of asking the setState related function to trigger render, so that it will not be redeclared, and you can get the "latest" value in the callback function clicked, but this method is not recommended. For this example, the input component displays null values from beginning to end because there is no rerender, which does not meet the operation expectations.
4. Use useRef instead of useState
Const btn = useRef (); const vRef = useRef (''); const [v, setV] = useStat (''); useEffect () = > {let clickHandle = () = > {console.log ('click', clickHandle) return () = > {btn.removeEventListener (' click', clickHandle)}}, []) Const inputHandle = e = > {let {value} = e.target vRef.current = value setV (value)} return (test)
The reason why useRef's scheme is effective is that every time the change of input modifies the current property of vRef, and vRef is always that vRef, even if rerender, because vRef is an object, the value of the variable stored in stack memory is the address of the object in heap memory, it is just a reference, only a property of the object is modified, and the reference will not change. So the scope chain in the click event always accesses the same vRef
5. Change v to object type
In fact, as with useRef, as long as it is an object, simply modifying a property does not change the address that the state points to.
This is the end of the introduction on "how to solve the problem of useEffect closure in react". Thank you for your reading. If you want to know more about the industry, you can follow the industry information channel. The editor will update different knowledge points for you every day.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.