useRef can store any mutable data that you want to persist between renders. It helps you to avoid re-rendering of the component when you don't want to.
useRef vs useState
useRef is similar to useState but there are some differences,
- both
useStateanduseRefcan maintain the value between renders. -
useStateis used to store the state of a component whereasuseRefis used to store any mutable value. -
useStatewill cause the component to re-render when the state is updated whereasuseRefwill not cause the component to re-render when the value is updated.
const [text, setText] = useState('') const handleTextChange = (e) => { setText(e.target.value) } // re-renders the component on every text change return ( <div> <input type="text" value={text} onChange={handleTextChange} /> </div> )
Using useRef to store the value of the input element will not cause the component to re-render when the value is updated.
const textRef = useRef('') const handleTextChange = (e) => { textRef.current = e.target.value } // no re-renders when the text changes return ( <div> <input type="text" value={textRef.current} onChange={handleTextChange} /> </div> )
useRef is mostly used for,
- storing the previous value of a state or props of a component across rendering of a component
- accessing DOM nodes in React
useRef to store the previous value of a state or props of a component
import React, { useState, useRef } from 'react' const Slide = ({ selectedSlideIndex }) => { const [slide, setSlide] = useState(selectedSlideIndex) const prevSlideRef = useRef() // update the previous slide value when the slide value changes useEffect(() => { prevSlideRef.current = slide }, [slide]) const prevSlide = prevSlideRef.current return ( <div> <p>Current slide: {slide}</p> <p>Previous slide: {prevSlide}</p> <button onClick={() => setSlide(slide + 1)}>Next</button> </div> ) }
In the above example, useRef helps to maintain the previous value of the slide state variable.
Some of the use cases are,
- undo/redo functionality
- maintaining the previous value of a state variable to compare with the current value and perform some action
- saving a draft if value of a textarea is changed
- showing a confirmation dialog if the value of a textarea is changed and the user tries to navigate away from the page
useRef to access DOM nodes
import React, { useRef, useEffect } from 'react' const Input = () => { const inputRef = useRef(null) // focus the input element when the component is mounted useEffect(() => { inputRef.current.focus() }, []) return ( <div> <input ref={inputRef} type="text" /> </div> ) }
In the above example, useRef helps to access the input element and focus it when the component is mounted.
Some of the use cases are,
- focusing or blurring an element
- accessing the DOM node to get the size of an element
- accessing the DOM node to get the scroll position of an element
Hope this helps to learn the magic of useRef hook. Happy referencing 😃