How to quickly get started with VUE3.0: Enter Learning
Hooks are used to use state and other React features without writing classes. So what exactly are Hooks, why should we use Hooks, what common Hooks does React provide, and how to customize Hooks? The following will reveal them to you one by one.
Hooks are translated as hooks. Hooks are functions within function components that are responsible for hooking into external functions.
React provides some common hooks, and React also supports custom hooks. These hooks are used to introduce external functions to functions.
When we need to introduce external functions into a component, we can use the hooks provided by React or customize hooks.
For example, if you introduce the function of managing state in a component, you can use the useState function. The usage of useState will be introduced in detail below.
Use Hooks There are two main reasons for using Hooks:
Before the emergence of Hooks, React had to borrow complex design patterns such as high-order components and render props to achieve logic reuse. However, high-order components will generate redundant component nodes, making debugging more complicated.
Hooks allow us to reuse state logic without modifying the component structure. The usage of custom Hooks will be introduced in detail below.
In class components, the code for the same business logic is scattered in different life cycle functions of the component, and Hooks can aggregate the code for the same business logic together, allowing the business logic to be clearly separated. , making the code easier to understand and maintain.
useState is a Hook that allows you to add state in React function components.
Usage examples are as follows:
import React, { useState } from 'react'; function Example() { // Declare a state variable called "count" const [count, setCount] = useState(0); // ...
The above code declares a state variable count with an initial value of 0, and updates the current count by calling setCount.
useEffect allows you to perform side effect operations in function components.
Side effects refer to a piece of code that has nothing to do with the current execution results. Common side effects operations include data acquisition, setting subscriptions, and manually changing the DOM in React components.
useEffect can receive two parameters, the code is as follows:
useEffect(callback, dependencies)
The first parameter is the function callback to be executed, and the second parameter is the optional dependencies array dependencies.
The dependency is optional. If it is not specified, the callback will be executed every time the function component is executed; if it is specified, it will only be executed when the value in the dependency changes.
Usage examples are as follows:
function Example() { const [count, setCount] = useState(0); // Similar to componentDidMount and componentDidUpdate: useEffect(() => { // Update the document title using the browser API document.title = `You clicked ${count} times`; return () => { // Can be used for clearing, equivalent to componentWillUnmount of class component } }, [count]); // Specify the dependency as count, and execute the side effect when count is updated // ...
The above code uses useEffect to implement the side effect function when the dependency count is updated, and clear it by returning the callback function The last execution result.
In addition, useEffect provides four timings for executing side effects:
The callback function defined by useCallback will only redeclare the callback function when the dependencies change, thus ensuring that the component will not create duplicate callback functions . The component that receives this callback function as an attribute will not need to be re-rendered frequently .
Usage examples are as follows:
const memoizedCallback = useCallback(() => { doSomething(a, b) }, [a, b])
The above code will redeclare the callback function only when dependencies a and b change.
The creation function defined by useMemo will only be recalculated when a certain dependency changes, which helps in high-overhead calculations that will not be repeated every time it is rendered, and the component that receives this calculated value as a property will not Frequent re-rendering is required .
Usage examples are as follows:
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b])
The above code will only be recalculated when dependencies a and b change.
useRef returns a ref object, which persists throughout the component's life cycle.
It has two uses:
An example of how to save a DOM node is as follows:
function TextInputWithFocusButton() { const inputEl = useRef(null) const onButtonClick = () => { // `current` points to the text input element inputEl.current.focus() that has been mounted on the DOM } return ( <> <input ref={inputEl} type='text' /> <button onClick={onButtonClick}>Focus the input</button> </> ) }
The above code creates a ref object through useRef, saves the reference of the DOM node, and can perform DOM operations on ref.current.
An example of sharing data between multiple renders is as follows:
import React, { useState, useCallback, useRef } from 'react' export default function Timer() { //Define time state to save the accumulated time of timing const [time, setTime] = useState(0) // Define timer. Such a container is used to save a variable between cross-component renderings const timer = useRef(null) // Event handler function to start timing const handleStart = useCallback(() => { // Use the current attribute to set the value of ref timer.current = window.setInterval(() => { setTime((time) => time + 1) }, 100) }, []) //Pause timing event handling function const handlePause = useCallback(() => { // Use clearInterval to stop timing window.clearInterval(timer.current) timer.current = null }, []) return ( <div> {time / 10} seconds. <br /> <button onClick={handleStart}>Start</button> <button onClick={handlePause}>Pause</button> </div> ) }
The above code creates a ref object with a variable name of timer through useRef. This object can be called when rendering across components, create a new timer when starting timing, and clear the timer when timing is paused.
useContext is used to receive a context object and return the value of the context, which can achieve cross-level data sharing.
An example is as follows:
//Create a context object const MyContext = React.createContext(initialValue) function App() { return ( // Pass the value of context through Context.Provider <MyContext.Provider value='1'> <Container /> </MyContext.Provider> ) } function Container() { return <Test /> } function Test() { // Get the value of Context const theme = useContext(MyContext) // 1 return <div></div> }
The above code obtains the Context defined in the App component through useContext, achieving data sharing across hierarchical components.
useReducer is used to introduce the Reducer function.
An example is as follows:
const [state, dispatch] = useReducer(reducer, initialState)
It accepts the Reducer function and the initial value of the state as parameters and returns an array. The first member of the array is the current value of the state, and the second member is the dispatch function that sends the action.
Through custom Hooks, component logic can be extracted into reusable functions.
Custom Hooks are functions, which have two characteristics that distinguish them from ordinary functions:
An example is as follows:
import { useState, useCallback } from 'react' function useCounter() { // Define count, this state is used to save the current value const [count, setCount] = useState(0) // Implement the operation of adding 1 const increment = useCallback(() => setCount(count + 1), [count]) // Implement the operation of decrement by 1 const decrement = useCallback(() => setCount(count - 1), [count]) //Reset counter const reset = useCallback(() => setCount(0), []) // Export the business logic operations for the caller to use return { count, increment, decrement, reset } } // component 1 function MyComponent1() { const { count, increment, decrement, reset } = useCounter() } // component 2 function MyComponent2() { const { count, increment, decrement, reset } = useCounter() }
The above code easily reuses business logic between the MyComponent1 component and the MyComponent2 component by customizing Hooks useCounter.
React officially provides the react-use library, which encapsulates a large number of custom Hooks that can be used directly, helping us simplify the internal logic of components and improve code readability and maintainability.
Among them, our commonly used custom Hooks are:
You can go to the react-use official website to learn how to use it.
This article introduces React Hooks from four aspects: what Hooks are, why to use Hooks, what common Hooks React provides, and how to customize Hooks. I believe that everyone has a deeper understanding of React Hooks.
Hope it helps you, thanks for reading~