– recently wrote a (ancient) auto-feed component that uses react-hooks, which include the useState, useEffect hooks, and (some of us) the less familiar useRef, useCallback.

The focus of this article is not to teach you how to implement a rotation component, but to let you understand the two hooks of useRef and useCallback through actual practice and combined with business requirements, know their general use, and can remember to use them when meeting specific requirements.

shuffling

As we all know, there are two requirements. The first one is automatic rotation. Second, there should be a click function, click which, which to play, and to reset the round broadcast time.

First of all, the first requirement is to set a timer, continuously add, count, if the array length is exceeded, then reset the counter, continue to round from the beginning; The second point is to add a click event, click to reset the timer, and then from the current click, continue to play.

So the set timer method needs to be used in two places, and must be extracted as a function.

The function extracted from the field code is called start.

useRef

One of the most common scenarios used by useRef is to load third-party resources, such as echarts or Amap. When a DOM node is passed in for initialization, useRef is used to store the node. But in this case, useRef is not used to save nodes, but to save ids returned by setInterval timers.

From my personal experience, useRef in functional components is similar to the way useRef in class components store variables and data across the life cycle without triggering re-rendering.

The basic usage method is as follows (the following example is only a simple example, no practical significance 😄)

import React, { useRef, useEffect } from 'react';
function A(){
	const timer = useRef();
	useEffect(() =>{
		timer.current = setInterval(()=>{
		 // XXXX
		})
		return () => clearInterval(timer.current)
	},[])
	return (
		<div />
	)
}
Copy the code

useCallback

We define A method B in A functional component A, and when A re-renders (executes), the method B inside it will actually be regenerated, meaning its reference will point to A new address.

import React, { useEffect } from 'react'; Function A(){function b(){return 'this is b method '; } useEffect(()=>{ fetch('XXXXXX' + b()); }, [b]); return ( <div>{b()}</div> ) }Copy the code

If we pass the second useEffect parameter to function B as A dependency, it will not work because the first useEffect method will be re-executed every time component A is re-rendered.

This is where useCallback comes in. We wrap B with useCallback and pass in the parameters that B depends on as follows

const bUseCallback = useCallback(b, []); useEffect(()=>{ fetch('XXXXXX' + bUseCallback()); }, [bUseCallback]) // Pass in this dependency, is the correct way!Copy the code

code

With a bit of explanation for the hooks above, I’ll go straight to the code

import React, { useState, useEffect, useRef, useCallback } from 'react'; function Carousel(props) { const { data = [], time } = props; const [active, setActive] = useState(0); const timer = useRef(); Const start = useCallback(() => {if (timer.current) {clearInterval(timer.current); } const len = data.length; timer.current = setInterval(() => { setActive((v) => { if (v >= len - 1) { return 0; } return v + 1; }); }, time); }, [data, time]); useEffect(() => { start(); return () => clearInterval(timer.current); }, [start]); function handleClick(i) { setActive(i); start(); } return ( <div> { data.map((item, index) => ( <div key={item} style={{ color: index === active ? 'red' : 'green' }} onClick={() => handleClick(index)} > {item} </div> )) } </div> ); } Carousel. DefaultProps = {time: props, // ms data: [' props ', 'props ',}; export default Carousel;Copy the code

conclusion

The above code logic is not complex, mainly has the following steps

  1. throughuseStateSets a state that holds the current activation item. One thing to note is that the callsetXXXWhen updating your status, it’s best to update it functionally so that you get the latest status every time.
  2. Extract thestartMethod to enable when needed
  3. withuseRefTo save the return of timerIDIn order to callclearIntervalempty
  4. Due to thestartMethod isuseEffectYou need to use theuseEffectPackage the

If you have any questions or mistakes, please contact us in the comments section 👏👏👏