三个必不可少的反应钩子将为您的下一个 Web 应用程序提供强大的动力。

2025-06-08

三个必不可少的反应钩子将为您的下一个 Web 应用程序提供强大的动力。

说实话,我们都想成为更优秀的 React 开发者。我们都经历过那种在开发待办事项应用或天气应用时感觉自己很牛逼的经历。现在是时候继续前进,学习一些高级的 React Hooks 了,它们能帮助我们构建更酷炫、更复杂的 Web 应用。

深入了解并理解这三个高级 React Hooks 的实际用途。

  • useEffect
  • useReducer
  • useContext

useEffect 钩子

为了更好地理解 useEffect,我们需要注意两件重要的事情:

React 的主要作用是什么?

React 的主要工作是渲染 UI,响应用户与 UI 的交互,然后根据交互类型重新渲染 UI。React 作为一个库唯一关心的就是将 UI 呈现到屏幕上。

有何副作用?

在我们的反应组件内部发生的所有此类任务/操作与将 UI 显示在屏幕上没有直接关系,但在某些情况下是绝对必要的(例如 - 要用数据填充 UI,我们需要从外部 API 源获取数据)以产生最终结果(或 UI)可以被视为副作用。

类似操作

  • 向远程服务器发送 HTTP 请求并处理潜在错误。所有现代 Web 应用都具备此功能,我们无需专门为此引入 React 机制。
  • 将数据存储在浏览器的本机存储中。
  • 设置和管理计时器等。

所有这些任务都必须在正常的组件评估和渲染周期之外进行,特别是因为这些任务可能会延迟/阻止 UI 的渲染。

我们使用 useEffect hook 来处理此类与副作用相关的代码,简单来说,这个 hook 为此类潜在的性能密集型代码创建了一个入口,这样这段代码将在正常的组件评估之外执行,并且不会妨碍 UI 的渲染。

useEffect hook 需要 2 个参数 -

  • 具有副作用的匿名函数。
  • 依赖数组允许我们控制钩子并让我们确定何时调用钩子。

句法

import { useEffect } from "react";

function App() {

 useEffect(()=> {
   //side-effect code
 }, [x, y]) // x, y are placeholders for state/props/methods.

 return (
   // JSX
 );
};
Enter fullscreen mode Exit fullscreen mode

使用 useEffect hook 时需要注意的事项 -

  • 这个包含副作用代码的匿名箭头函数仅在组件评估完成后执行。
  • 如果依赖项数组为空数组 [ ],则 useEffect 将仅在组件首次挂载后运行一次。
  • 当依赖项之一更新时,会触发 useEffect。依赖项可以是 state 或 props。由于依赖项数组中的某一项在上一个组件渲染/评估周期中已更新,因此在 React 完成组件评估后,useEffect 会再次运行。
  • 当组件卸载 DOM 时触发 useEffect。

警告

import { useEffect } from "react";

function App() {

 useEffect(()=> {
   //side-effect code
 }, ) // No dependency array

 return (
   // JSX
 );
};
Enter fullscreen mode Exit fullscreen mode

和...相同

function App() {

 //side-effect code
//this code will be executed everytime the component is re evaluated

 return ( 
   // JSX
 );
};
Enter fullscreen mode Exit fullscreen mode

我们绝不能忽略第二个参数,否则我们将无法利用 useEffect 钩子的优势。

一些规则将有助于决定我们应该在依赖数组中提及什么:

  • 不要添加“内置” API 或函数,例如 fetch()、localStorage 等(这些函数和特性是浏览器内置的,因此可以全局使用)。这些浏览器 API/全局函数与 React 组件的渲染周期无关,并且永远不会改变。
  • 不要添加我们可能在组件外部定义的变量或函数(例如,单独文件中的辅助函数)此类函数或变量不会在组件函数内部创建,因此更改它们不会影响您的组件。
  • 不要添加状态更新函数,React 保证这些函数永远不会改变,因此我们不需要将它们添加为依赖项(但你可以)。

useEffect 清理

副作用有两种类型:一种需要清理,另一种不需要。此外,useEffect 中执行的操作类型也可能存在问题。如果是性能密集型代码,则可能会降低应用速度;如果我们发送 HTTP 请求来检查登录信息是否正确,我们当前的 useEffect 会
发送大量不必要的请求,从而导致网络流量。

句法
import { useEffect } from "react";

function App() {

 useEffect(()=> {
   //side-effect code

  return () => {}

 }, [x, y]) // x, y are placeholders for state/props/methods.

 return (
   // JSX
 );
};
Enter fullscreen mode Exit fullscreen mode

笔记:

  1. 当 useEffect 第一次运行时,即当组件挂载 DOM 时,清理不会运行。
  2. 现在,对于点 (1) 之后的每次 useEffect 执行,清理将首先运行,然后才运行副作用代码。
  3. 当组件卸载 DOM 时,清理运行。

何时使用 useEffect

  • 控制一段代码。
  • 避免潜在的无限循环,因为我们正在触发组件内部的状态更新。
  • 它还有助于避免在每次组件重新评估时运行性能密集型代码。

useReducer() 钩子

这是另一个内置的 React Hook,它有助于状态管理。
此 Hook 用于管理 React 组件中的复杂状态。它为状态添加了更多结构,并将所有导致状态更新的方法组合到一个地方。
它接受一个 type 的 reducer (state, action) => newState,并返回当前状态以及一个 dispatch 方法。(如果您熟悉 Redux,那么您已经知道它的工作原理。)

我们可以像其他 React hooks 一样从 react 导入 useReducer,如以下代码片段所示:

import React, { useReducer } from 'react';
const [state, dispatch] = useReducer(reducer, initialState);
Enter fullscreen mode Exit fullscreen mode

这个钩子函数返回一个包含两个值的数组。第一个值是状态值,第二个值是调度函数,该函数借助数组解构进一步触发操作。

当您具有涉及多个子值的复杂状态逻辑或下一个状态取决于前一个状态时,useReducer 通常比 useState 更可取。useReducer 还允许您优化触发深度更新的组件的性能,因为您可以向下传递调度而不是回调。

这里有一个例子来更好地理解 useReducer 钩子。

// reducer function
const initialState = {count: 0};

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return {count: state.count + 1};
    case 'decrement':
      return {count: state.count - 1};
    default:
      throw new Error();
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

useContext

useContext hook 允许您轻松共享应用程序范围或组件范围的状态和状态更新方法。

但是,我们首先需要了解 useContext hook 的必要性是什么?

什么是支柱钻井?

当我们需要将状态或方法从组件树顶层的组件向下传递到底层的组件时,即使对那些并不需要的组件,我们也必须传递 props,因为它们仅仅充当了载体组件的角色。随着组件树变得越来越大,将 props 和方法传递给每个组件变得越来越复杂,这时 useContext hook 就派上用场了。

首先创建一个上下文:

AuthContext.js


import { createContext } from "react";

// Create context object
// Takes a default context in argument.
// Context -> App  or component wide state.

// AuthContext is an object that contains a component
const AuthContext = createContext ( { 
    isLoggedIn : false,
} );

export default AuthContext;

Enter fullscreen mode Exit fullscreen mode

要在应用程序中使用上下文,我们需要执行以下操作 -

  1. 提供它 = 它包装的所有组件都应该可以访问它。
  2. 消费它 -> 沉迷于它 -> 聆听它

App.js ->


import AuthContext from './store/auth-context';

function App () {
  // Something
   return ( 
     // AuthContext is just an object, whose .Provider proprty is 
        a Component
    <AuthContext.Provider>
      // JSX
     // root component here
    // Auth-Context provider is a component we can use in our JSX code, and we can wrap it around other components and those other components and all their descendant components. So all their children and their children's children and so on all those components will now have access to that Context.
    </AuthContext.Provider>
  );
}

Enter fullscreen mode Exit fullscreen mode

我们可以通过两种方式监听。我们可以通过使用 Auth-Context 消费者或使用 React Hook(推荐方式)进行监听。

这个钩子允许你利用上下文并使用它。

import React, { useContext } from 'react';

import AuthContext from './AuthContext.js';

const Navbar = (props) => {
  const ctx = useContext(AuthContext);

  return (
    <nav className={classes.nav}>
      <ul>
        {ctx.isLoggedIn && (
          <li>
            <a href="/">Users</a>
          </li>
        )}
      </ul>
     </nav>
)
Enter fullscreen mode Exit fullscreen mode

结论

这三个高级 React Hooks 能让你构建更强大、更健壮的前端 Web 应用程序。React Hooks 的广泛使用让构建现代 Web 应用变得更加轻松。

祝您编码愉快!

鏂囩珷鏉ユ簮锛�https://dev.to/ankur29mac/ Three-essential-react-hooks-that-will-supercharge-your-next-webapp-1jeo
PREV
为什么即使我对自己的工作很满意,我还是会去参加面试?
NEXT
Styled-Components:高效地在 JS 文件中编写 CSS。