Home >Web Front-end >CSS Tutorial >React Hooks: The Deep Cuts

React Hooks: The Deep Cuts

Joseph Gordon-Levitt
Joseph Gordon-LevittOriginal
2025-03-11 10:34:20432browse

React Hooks: The Deep Cuts

Hooks are reusable functions that allow you to use state and other functions (such as lifecycle methods, etc.) without writing classes. Hook functions allow us to "hook" the React state lifecycle using function components, allowing us to manipulate the state of the function component without converting it into a class component.

React introduced Hooks in version 16.8 and has been adding more Hooks since then. Some Hooks are more commonly used and popular than others, such as useEffect, useState, and useContext. If you use React, I believe you must have used these Hooks.

But what I'm interested in is the little-known React Hooks. While all React Hooks have their own features, I really want to show you five Hooks because they may not appear in your day-to-day job – or maybe, knowing that they give you some extra superpowers.

Catalog

  • useReducer
  • useRef
  • useImperativeHandle
  • useMemo
  • useCallback
  • Summary

useReducer

useReducer Hook is a status management tool similar to other Hooks. Specifically, it is an alternative to the useState Hook.

If you use the useReducer Hook to change two or more states (or actions), you do not need to operate them separately. The Hook tracks all states and manages them collectively. In other words: it manages and re-renders state changes. Unlike the useState Hook, useReducer is easier when dealing with many states in complex projects.

Usage Scenario

useReducer can help reduce the complexity of handling multiple states. It can be used when you find yourself needing to track multiple states collectively, as it allows you to treat the state management and rendering logic of components as separate concerns.

Syntax

useReducer accepts three parameters, one of which is optional:

  • A reducer function
  • initialState
  • an init function (optional)
const [state, dispatch] = useReducer(reducer, initialState) const [state, dispatch] = useReducer(reducer, initialState, initFunction) // Initialization using an optional third parameter

Example

The following example is an interface containing text input, counters, and buttons. Interacting with each element will update the status. Note that useReducer allows us to define multiple cases at once, rather than setting them separately.

import { useReducer } from 'react'; const reducer = (state, action) => { switch (action.type) { case 'INCREMENT': return { ...state, count: state.count 1 }; case 'DECREMENT': return { ...state, count: state.count - 1 }; case 'USER_INPUT': return { ...state, userInput: action.payload }; case 'TOGGLE_COLOR': return { ...state, color: !state.color }; default: throw new Error(); } } function App() { const [state, dispatch] = useReducer(reducer, { count: 0, userInput: '', color: false }) return ( <main classname="App App-header"   style="max-width:90%" backgroundcolor: state.color :> <input type="text" onchange="{(e)"> dispatch({ type: 'USER_INPUT', payload: e.target.value })} /> <br><br><p style="{{" margin:>{state.count}</p> <button onclick="{()"> dispatch({ type: 'DECREMENT' })}>-</button> <button onclick="{()"> dispatch({ type: 'INCREMENT' })}> </button> <button onclick="{()"> dispatch({ type: 'TOGGLE_COLOR' })}> Color</button>  <button onclick="{()"> dispatch({ type: 'TOGGLE_COLOR' })}>Color</button> <br><br><p style="{{" margin:>{state.userInput}</p> </main> ); } export default App;

From the above code, you can notice that we can easily manage multiple states in reducer (switch-case), which demonstrates the advantages of useReducer. This is the power it provides when working in complex applications with multiple states.

useRef

useRef Hook is used to create references on elements to access the DOM. But not only that, it returns an object with the .current attribute, which can be used throughout the life of the component, allowing data to be persisted without causing re-rendering. Therefore, the useRef value remains unchanged between renders; updating the reference does not trigger re-rendering.

Usage Scenario

When you want to:

  • Manipulate the DOM with stored variable information.
  • Access information in child components (necked elements).
  • Set focus on the element.

The useRef Hook can be used. It is most useful when storing variable data in your application without causing re-rendering.

Syntax

useRef only accepts one parameter, i.e. initial value.

const newRefComponent = useRef(initialValue);

Example

Here, I used the useRef and useState Hook to show how many times the application re-renders the update state as it types in text input.

import './App.css' function App() { const [anyInput, setAnyInput] = useState(" "); const showRender = useRef(0); const randomInput = useRef(null); // Note that null needs to be set here const toggleChange = (e) => { setAnyInput(e.target.value); showRender.current ; } const focusRandomInput = () => { if (randomInput.current) { // Add judgment to prevent null reference errors randomInput.current.focus(); } } return ( <div classname="App"> <h3>Amount Of Renders: {showRender.current}</h3> <input type="text" ref="{randomInput}" onchange="{toggleChange}"> <button onclick="{focusRandomInput}">Click To Focus On Input</button> </div> ); } export default App;

Note that typing each character in the text field will update the application's status, but will not trigger a full re-render.

useImperativeHandle

Do you know how child components access the functionality passed to them from parent components? Parent components pass these functions through props, but this kind of pass is in a sense "one-way" because the parent component cannot call functions in the child component.

Then, useImperativeHandle enables parent components to access functions of children.

How does this work?

  • Define a function in a child component.
  • Add a ref in the parent component.
  • We use forwardRef, which allows the defined ref to be passed to child components.
  • useImperativeHandleExposes functions of child components through ref.

Usage Scenario

useImperativeHandle works well when you want the parent component to be affected by changes in the child component. So, cases like changing focus, increasing and decreasing, and blurring elements may be cases where you find yourself needing to use this Hook in order to update the parent component accordingly.

Syntax

useImperativeHandle(ref, createHandle, [dependencies])

Example

In this example, we have two buttons, one in the parent component and one in the child component. Clicking the parent button allows us to retrieve data from the child component, allowing us to manipulate the parent component. It is set up in that clicking the child button does not pass anything from the parent component to the child component to help illustrate how we pass the content in the opposite direction.

// Parent component import React, { useRef } from "react"; import ChildComponent from "./childComponent"; import './App.css'; function ParentComponent() { const controlRef = useRef(null); return ( <div> <button onclick="{()"> { if (controlRef.current) { controlRef.current.controlPrint(); } }}>Parent Box</button> <childcomponent ref="{controlRef}"></childcomponent> </div> ); } export default ParentComponent;
// Child component import React, { forwardRef, useImperativeHandle, useState } from "react"; const ChildComponent = forwardRef((props, ref) => { const [print, setPrint] = useState(false); useImperativeHandle(ref, () => ({ controlPrint() { setPrint(!print); }, })); return ( <div> <button>Child Box</button> {print && <p>I am from the child component</p>} </div> ); }); export default ChildComponent;

Output

...(Sample output screenshot or description should be included here)

useMemo

useMemo is one of the least commonly used but interesting React Hooks. It improves performance and reduces latency, especially in large computing in applications. How could this happen? The useMemo Hook prevents React from recalculating the value every time the component's state is updated and the component is re-rendered.

You will see that the function responds to state changes. useMemo Hook accepts a function and returns the return value of the function. It caches the value to prevent extra work from being spent to re-render it, and then returns it when one of the dependencies changes.

This process is called memorization, which helps improve performance by remembering the previously requested value so that it can be used again without repeating all these calculations.

Usage Scenario

The best use case will be any time you are dealing with heavy calculations that you want to store the value and use it in subsequent state changes. It can bring a nice performance boost, but overuse of it can have the exact opposite effect, thus taking up the application's memory.

Syntax

useMemo(() => { // Code here}, [])

Example

When the button is clicked, this mini program indicates whether the number is an even or an odd number, and then squares the value. I've added many zeros to the loop to increase its computational power. It returns the value in seconds and is still working fine due to the useMemo Hook.

// UseMemo.js import React, { useState, useMemo } from 'react' function Memo() { const [memoOne, setMemoOne] = useState(0); const incrementMemoOne = () => { setMemoOne(memoOne 1) } const isEven = useMemo(() => { let i = 0; while (i < 1000000000) { i } //Increase the calculation amount return memoOne % 2 === 0; }, [memoOne]); const squaredNumber = useMemo(() => { let i = 0; while (i < 100000000) { i } //Increase the calculation amount console.log("squared the number"); return memoOne * memoOne; }, [memoOne]); return ( <div> <h1>{memoOne}</h1> <button onClick={incrementMemoOne}>Increment</button> <p>Is Even: {isEven ? &#39;Yes&#39; : &#39;No&#39;}</p> <p>Squared Number: {squaredNumber}</p> </div> ); } export default Memo;

output

...(The sample output screenshot or description should be included here)

useMemo is a bit like a useCallback Hook, but the difference is that useMemo can store memorized values ​​from a function, while useCallback stores and returns the function itself.

useCallback

useCallback The Hook is another interesting Hook, and the previous section is a spoiler of its features.

As we just saw, useCallback works similarly to useMemo Hooks, because they all use memory to cache certain content for later use. useMemo stores the function's calculation as a cached value, while useCallback stores and returns the function.

Usage Scenario

Like useMemo, useCallback is a good performance optimization because it stores and returns memorized callbacks and any of its dependencies without re-rendering.

Syntax

const getMemoizedCallback = useCallback( () => { doSomething() }, [] );

Example

import React, { useCallback, useState } from "react"; import CallbackChild from "./UseCallback-Child"; import "./App.css" export default function App() { const [toggle, setToggle] = useState(false); const [data, setData] = useState("I am a data that would not change at every render, thanks to the useCallback"); const returnFunction = useCallback( (name) => { return data name; }, [data] ); return ( <div> <button onclick="{()"> { setToggle(!toggle); }}> {/* Click To Toggle */} </button> {toggle && <h1>Toggling me no longer affects any function</h1>} <callbackchild returnfunction="{returnFunction}"></callbackchild> </div> ); }

// Subcomponent

import React, { useEffect } from "react"; function CallbackChild({ returnFunction }) { useEffect(() => { console.log("FUNCTION WAS CALLED"); }, [returnFunction]); return <p>{returnFunction(" Hook!")}</p>; } export default CallbackChild;

Output

...(Sample or description of the sample output should be included here)

Summary

That's it! We just looked at five very handy React Hooks that I think are often overlooked. Like many such reviews, we just touch the surface of these Hooks. They each have their own subtleties and precautions that need to be considered when using them. But hopefully you have a good advanced concept for what they are and when they are better suited than other Hooks you may use more often.

The best way to fully understand them is practice. Therefore, I encourage you to practice using these Hooks in your app to better understand them. To do this, you can learn more about it by looking at the following resources:

<code>- Intro to React Hooks (Kingsley Silas) - Hooks at a Glance (React documentation) - Hooks Cheatsheet (Ohans Emmanuel) - The Circle of a React Lifecycle (Kingsley Silas) - Hooks of React Router (Agney Menon) - Testing React Hooks With Enzyme and React Testing Library (Kingsley Silas)</code>

The above is the detailed content of React Hooks: The Deep Cuts. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn