Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to solve the pit of React Hooks and setInterval

2025-04-02 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)05/31 Report--

This article mainly explains "how to solve the pit of React Hooks and setInterval". The content of the explanation is simple and clear, and it is easy to learn and understand. Please follow the editor's train of thought to study and learn how to solve the pit of React Hooks and setInterval.

I. demand

We want to have a timer that automatically + 1 every second.

Function Counter () {let [count, setCount] = useState (0); useEffect () = > {let id = setInterval (()) = > {setCount (count + 1);}, 1000); return () = > clearInterval (id);}, [count]); return {count};}

In this way, you will find that the page effect does come out, but the performance is very poor. Whenever the count changes, the useEffect will be rendered once, and the timer will be constantly added and removed. The process is as follows:

/ / the first time function Counter () {/ /... UseEffect () = > {let id = setInterval (() = > {setCount (0 + 1);}, 1000); return () = > clearInterval (id);}, [0]); / /...} / / second function Counter () {/ /. UseEffect (() = > {let id = setInterval (() = > {setCount (1 + 1);}, 1000); return () = > clearInterval (id);}, [1]); / /. / / Nth}

Now our requirement is not only to realize the function, but also to make the timer monitor only once to ensure its high performance.

Solution 1. Functional update

The set method in useState receives a function that receives the previous state and returns an updated value. This way the timer gets the latest value each time.

Function Counter () {let [count, setCount] = useState (0); useEffect () = > {let id = setInterval (()) = > {setCount (v = > {return v + 1;});}, 1000); return () = > clearInterval (id);}, []); return {count};} 2, use useRef

UseRef returns a mutable ref object, and the returned ref object remains unchanged throughout the lifecycle of the component.

The timer function is extracted, and each time the timer is triggered, it can fetch the latest to count.

Function Counter () {let [count, setCount] = useState (0); const myRef = useRef (null); myRef.current = () = > {setCount (count + 1);}; useEffect () = > {let id = setInterval (() = > {myRef.current ();}, 1000); return () = > clearInterval (id);}, []); return {count};}

Think about it: why not just write setInterval as setInterval (myRef.current, 1000) as in the following example? Why return through a function?

/ / this example is the wrong function Counter () {let [count, setCount] = useState (0); const myRef = useRef (null); myRef.current = () = > {setCount (count + 1);}; useEffect () = > {let id = setInterval (myRef.current, 1000); return () = > clearInterval (id);}, []); return {count};}

The first parameter of the timer is the interval variable. If the myRef.current is assigned directly to the interval variable, then after the value of the myRef.current is changed, the value before the change will still be taken here, because the change of ref will not cause the component to re-render.

3. Use useReducer

Save the count variable into reducer and update the count with useReducer

Function reducer (state, action) {switch (action.type) {case "increment": return state + 1; default: throw new Error ();}} function Counter () {const [state, dispatch] = useReducer (reducer, 0); useEffect () = > {setInterval (()) = > {dispatch ({type: "increment"});}, []); return {state};} 4, custom hooks

Custom hook:useInterval

Import React, {useState, useEffect, useRef} from 'react'; function useInterval (callback, delay) {const savedCallback = useRef (); / / Save the new callback useEffect (() = > {savedCallback.current = callback;}); / / create interval useEffect (() = > {function tick () {savedCallback.current ();} if (delay! = null) {let id = setInterval (tick, delay); return () = > clearInterval (id) }}, [delay]);}

Use useInterval:

Function Counter () {let [count, setCount] = useState (0); useInterval () = > {/ / your own code setCount (count + 1);}, 1000); return {count};}

The design of the api useInterval is very ingenious.

First of all, useInterval and setInterval receive the same parameters, which reduces our learning cost.

Secondly, the delay parameters of useInterval can be adjusted dynamically, while the delay parameters of setInterval can not be adjusted dynamically.

When useInterval Hook receives a different delay, it resets the interval.

Declare an interval with dynamically adjusted delay instead of writing the code to add and remove * interval-useInterval Hook helps us do it.

If you want to pause interval temporarily, you can do something like this example

Const [delay, setDelay] = useState (1000); const [isRunning, setIsRunning] = useState (true); useInterval () = > {setCount (count + 1);}, isRunning? Delay: null)

UseInterval's delay can also be controlled by another useInterval.

Function Counter () {const [delay, setDelay] = useState (1000); const [count, setCount] = useState (0); / / increase counter useInterval (() = > {setCount (count + 1);}, delay); / / accelerate useInterval (() = > {if (delay > 10) {setDelay (delay / 2);}, 1000); function handleReset () {setDelay (1000) } return (Counter: {count} Delay: {delay} Reset delay);} Thank you for reading, the above is the content of "how to solve the pit of React Hooks and setInterval". After the study of this article, I believe you have a deeper understanding of how to solve this problem of React Hooks and setInterval, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!

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.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report