Home  >  Article  >  Web Front-end  >  This article will give you an in-depth understanding of React Hooks!

This article will give you an in-depth understanding of React Hooks!

青灯夜游
青灯夜游forward
2022-03-21 11:31:552302browse

Do you know Hooks in React? This article will give you an in-depth understanding of React Hooks. I hope it will be helpful to you!

This article will give you an in-depth understanding of React Hooks!

Preface

Hooks are used to use state and other React features without writing a class. 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. [Related recommendations: Redis Video Tutorial]

What are Hooks

Hooks is 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.

Why use Hooks

There are two main reasons for using Hooks:

  • Simplify logic reuse;
  • Make complex components easier to understand.

1. Simplify logic reuse

Before the emergence of Hooks, React had to borrow complex design patterns such as high-order components and render props to implement logic. Reuse, but 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.

2. Make complex components easier to understand

In class components, the code of the same business logic is scattered in different life cycle functions of the component, and Hooks can make Codes for the same business logic are aggregated together to clearly separate the business logic and make the code easier to understand and maintain.

4. Commonly used Hooks

1. useState

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() {
  // 声明一个叫 "count" 的 state 变量
  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.

2. useEffect

useEffect allows you to perform side effects 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 dependencies are optional. If not specified, the callback will be executed after each function component is executed; if specified, it will only be executed when the value in the dependency changes. will be executed.

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 () => {
        // 可用于做清除,相当于 class 组件的 componentWillUnmount
    }

  }, [count]); // 指定依赖项为 count,在 count 更新时执行该副作用
  // ...

The above code uses useEffect to implement when the dependency count is updated, the side effect function is executed, and the last execution result is cleared by returning the callback function.

In addition, useEffect provides four timings for executing side effects:

  • Executed after each render: The second dependency parameter is not provided. For example, useEffect(() => {});
  • Only executed after the first render: Provide an empty array as a dependency. For example, useEffect(() => {}, []);
  • Executed for the first time and after dependencies change: Provide an array of dependencies. For example, useEffect(() => {}, [deps]);
  • execute after the component is unmounted: return a callback function. For example useEffect() => { return () => {} }, []).

3. useCallback

The callback function defined by useCallback will only redeclare the callback function when the dependencies change, thus ensuring that the component Duplicate callback functions will not be created. 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.

4. useMemo

The creation function defined by useMemo will only be recalculated when a dependency changes, which helps not There will be repeated and expensive calculations , and the component that receives this calculated value as a property will not need to be re-rendered frequently.

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.

5. useRef

useRef returns a ref object that persists throughout the component's life cycle.

He has 2 uses:

  • 保存 DOM 节点的引用
  • 在多次渲染之间共享数据

保存 DOM 节点的引入使用示例如下:

function TextInputWithFocusButton() {
  const inputEl = useRef(null)
  const onButtonClick = () => {
    // `current` 指向已挂载到 DOM 上的文本输入元素
    inputEl.current.focus()
  }
  return (
    <>
      <input ref={inputEl} type=&#39;text&#39; />
      <button onClick={onButtonClick}>Focus the input</button>
    </>
  )
}

以上代码通过 useRef 创建了 ref 对象,保存了 DOM 节点的引用,可以对 ref.current 做 DOM 操作。

在多次渲染之间共享数据示例如下:

import React, { useState, useCallback, useRef } from &#39;react&#39;

export default function Timer() {
  // 定义 time state 用于保存计时的累积时间
  const [time, setTime] = useState(0)

  // 定义 timer 这样一个容器用于在跨组件渲染之间保存一个变量
  const timer = useRef(null)

  // 开始计时的事件处理函数
  const handleStart = useCallback(() => {
    // 使用 current 属性设置 ref 的值
    timer.current = window.setInterval(() => {
      setTime((time) => time + 1)
    }, 100)
  }, [])

  // 暂停计时的事件处理函数
  const handlePause = useCallback(() => {
    // 使用 clearInterval 来停止计时
    window.clearInterval(timer.current)
    timer.current = null
  }, [])

  return (
    <div>
      {time / 10} seconds.
      <br />
      <button onClick={handleStart}>Start</button>
      <button onClick={handlePause}>Pause</button>
    </div>
  )
}

以上代码通过 useRef 创建了一个变量名为 timer 的 ref 对象,该对象可以在跨组件渲染时调用,在开始计时时新建计时器,在暂停计时时清空计时器。

6. useContext

useContext 用于接收一个 context 对象并返回该 context 的值,可以实现跨层级的数据共享。

示例如下:

// 创建一个 context 对象
const MyContext = React.createContext(initialValue)
function App() {
  return (
    // 通过 Context.Provider 传递 context 的值
    <MyContext.Provider value=&#39;1&#39;>
      <Container />
    </MyContext.Provider>
  )
}

function Container() {
  return <Test />
}

function Test() {
  // 获取 Context 的值
  const theme = useContext(MyContext) // 1
  return <div></div>
}

以上代码通过 useContext 取得了 App 组件中定义的 Context,做到了跨层次组件的数据共享。

7. useReducer

useReducer 用来引入 Reducer 功能。

示例如下:

const [state, dispatch] = useReducer(reducer, initialState)

它接受 Reducer 函数和状态的初始值作为参数,返回一个数组。数组的第一个成员是状态的当前值,第二个成员是发送 action 的 dispatch 函数。

五、自定义 Hooks

通过自定义 Hooks,可以将组件逻辑提取到可重用的函数中。

1. 如何创建自定义 Hooks?

自定义 Hooks 就是函数,它有 2 个特征区分于普通函数:

  • 名称以 “use” 开头;
  • 函数内部调用其他的 Hook。

示例如下:

import { useState, useCallback } from &#39;react&#39;

function useCounter() {
  // 定义 count 这个 state 用于保存当前数值
  const [count, setCount] = useState(0)
  // 实现加 1 的操作
  const increment = useCallback(() => setCount(count + 1), [count])
  // 实现减 1 的操作
  const decrement = useCallback(() => setCount(count - 1), [count])
  // 重置计数器
  const reset = useCallback(() => setCount(0), [])

  // 将业务逻辑的操作 export 出去供调用者使用
  return { count, increment, decrement, reset }
}

// 组件1
function MyComponent1() {
  const { count, increment, decrement, reset } = useCounter()
}

// 组件2
function MyComponent2() {
  const { count, increment, decrement, reset } = useCounter()
}

以上代码通过自定义 Hooks useCounter,轻松的在 MyComponent1 组件和 MyComponent2 组件之间复用业务逻辑。

2. 自定义 Hooks 库 - react-use

React 官方提供了 react-use 库,其中封装了大量可直接使用的自定义 Hooks,帮助我们简化组件内部逻辑,提高代码可读性、可维护性。

其中我们常用的自定义 Hooks 有:

  • useLocation 和 useSearchParam:跟踪页面导航栏位置状态;
  • useScroll:跟踪 HTML 元素的滚动位置;
  • useScrolling:跟踪 HTML 元素是否正在滚动;
  • useAsync, useAsyncFn, and useAsyncRetry:解析一个 async 函数;
  • useTitle:设置页面的标题。

可至 react-use 官网学习使用。

六、小结

本文从 Hooks 究竟是什么,为什么要使用 Hooks,React 提供了哪些常用 Hooks,以及如何自定义 Hooks 4 个方面介绍了 React Hooks,相信大家对 React Hooks 已经有了更加深入的理解。

希望能对你有所帮助,感谢阅读~

更多编程相关知识,请访问:编程入门!!

The above is the detailed content of This article will give you an in-depth understanding of React Hooks!. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:juejin.cn. If there is any infringement, please contact admin@php.cn delete