This series will cover the use of React Hooks, starting with useState, and will include the following:

  • useState
  • useEffect
  • useContext
  • useReducer
  • useCallback
  • useMemo
  • useRef
  • custom hooks

Learn the React Hooks API to help you use React in your work. This series uses a lot of sample code and effect demonstrations, making it easy for beginners and refreshers to use.

Next we’ll learn about the useRef Hook, which allows direct access to the Dom nodes in the component. Let’s take a look at useRef today using an input field to get focus as an example.

The page loads input to get the focus sample

FocusInput.tsx

import React, { useEffect, useRef} from 'react'

function FocusInput() {
  const inputRef = useRef<HTMLInputElement>(null)
  useEffect(() = > {
    inputRef.current && inputRef.current.focus()
  }, [])

  return (
    <div>
      <input ref={inputRef} type="text" />
    </div>)}export default FocusInput
Copy the code

App.tsx

import React from 'react'
import './App.css'

import FocusInput from './components/28FocusInput'

const App = () = > {
  return (
    <div className="App">
      <FocusInput />
    </div>)}export default App
Copy the code

Page display effect

Note how with TypeScript, generics need to be declared first

const inputRef = useRef<HTMLInputElement>(null)
Copy the code

Nullification is required for simultaneous use

inputRef.current && inputRef.current.focus()
Copy the code

See the TypeScript and React: hooks article for details on how to combine TS and hooks.

UseRef returns a mutable ref object whose.current property is initialized as the passed parameter (initialValue). The ref object returned remains constant throughout the life of the component.

Refs provides a way to access DOM nodes or React elements created in the Render method.

In a typical React data flow, the props is the only way for the parent component to interact with its children. To modify a child component, you need to re-render it using new props. However, in some cases, you need to force changes to subcomponents outside of the typical data flow. The child component being modified may be an instance of the React component or a DOM element. React offers solutions in both cases.

Here are a few situations where refs are appropriate

  • Manage focus, text selection or media playback.
  • Trigger the forced animation.
  • Integrate third-party DOM libraries.

Avoid using Refs for anything that can be done with a declarative implementation. For example, avoid exposing the open() and close() methods in the Dialog component and pass the isOpen property instead.

Don’t overuse Refs

The first thing you might think of is using Refs to “make things happen” in your app. If this is the case, take a moment and seriously reconsider which component layer the state property should be placed in. In general, you might think it would be more appropriate to have this state at a higher component level. See status promotions for more examples.

For more information about refs and the Dom, visit refs and the Dom at React

Let’s look at the use of useRef in another scenario.

Examples of timers that can be stopped

The requirement is that there is a timer on the page that automatically increases by one every second, and there is a button that stops the timer when clicked. Use the Class component to do this first

Class Component Example

ClassTimer.tsx

import React, { Component } from 'react'

export default class ClassTimer extends Component<{}, { timer: number }> { interval! : numberconstructor(props: Readonly<{}>) {
    super(props)
    this.state = {
      timer: 0}}componentDidMount() {
    this.interval = window.setInterval(() = > {
      this.setState(prevState= > ({
        timer: prevState.timer + 1}})),1000)}componentWillUnmount() {
    clearInterval(this.interval)
  }

  render() {
    return (
      <div>
        Timer - {this.state.timer}
        <br/>
        <button
          onClick={()= > {
            clearInterval(this.interval)
          }}
        >Clear Timer</button>
      </div>)}}Copy the code

App.tsx

import React from 'react'
import './App.css'

import ClassTimer from './components/29ClassTimer'

const App = () = > {
  return (
    <div className="App">
      <ClassTimer />
    </div>)}export default App
Copy the code

The page display is as follows

Function component example

HookTimer.tsx

import React, { useState, useEffect, useRef } from 'react'

function HookTimer() {
  const [timer, setTimer] = useState(0)

  // @ts-ignore
  const intervalRef = useRef(null) as { current: number }

  useEffect(() = > {
    intervalRef.current = window.setInterval(() = > {
      setTimer(pre= > pre + 1)},1000)
    return () = > {
      clearInterval(intervalRef.current)
    }
  }, [])
  return (
    <div>
      HookTimer - {timer}
      <br />
      <button
        onClick={()= > {
          clearInterval(intervalRef.current)
        }}
      >Clear Hook Timer</button>
    </div>)}export default HookTimer
Copy the code

App.tsx

import React from 'react'
import './App.css'

import ClassTimer from './components/29ClassTimer'
import HookTimer from './components/29HookTimer'

const App = () = > {
  return (
    <div className="App">
      <ClassTimer />
      <hr />
      <HookTimer />
    </div>)}export default App
Copy the code

The page display is as follows

This is the second use of useRef to create a generic container for holding variables.

summary

In this chapter, we learned that useRef can be used in two ways: one allows us to access Dom nodes; The other is to become a container for caching variables. The second usage is less common and requires more attention, and can be used in similar situations.