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.