React useEffect Hook

摘要:在本教程中,您将探索 React useEffect() hook,并学习如何以及何时正确使用它。

理解 React useEffect hook

在 React 中,副作用包括数据获取、手动 DOM 操作或任何其他影响组件外部的操作。

要在函数组件中执行副作用,您使用 useEffect hook。要使用 useEffect hook,您首先需要从 react 库中导入它。

import { useEffect } from 'react';Code language: JavaScript (javascript)

然后,您可以使用以下语法在您的组件中使用它。

useEffect(setup, dependencies)Code language: JavaScript (javascript)

useEffect hook 是一个接受两个参数的函数。

  • setup 是包含副作用的主要函数,您希望执行它。
  • dependencies 是一个可选的依赖值数组,它决定了 setup 函数何时运行。useEffect hook 将根据 dependencies 数组中指定的 items 来运行 setup 函数。

setup 函数可以选择返回一个清理函数。

return cleanup;Code language: JavaScript (javascript)

React 在卸载组件或 setup 重新运行之前执行 cleanup 函数(除了第一次)。

cleanup 函数中,您可以包含用于清理资源的代码,例如清除间隔或取消网络请求 (AbortController)。

通常,您会按如下方式编写 useEffect hook。

useEffect(() => {
  // Side effect code here

  return () => {
    // Cleanup code here (optional)
  };
}, [dependencies]);Code language: JavaScript (javascript)

在此语法中,您为 setup 函数定义一个箭头函数。

() => {
  // Side effect code here

  return () => {
    // Cleanup code here (optional)
  };
}Code language: JavaScript (javascript)

并在 dependencies 数组中包含值。

[dependencies]Code language: JavaScript (javascript)

只运行一次效果

要仅在组件挂载时运行效果(或函数),请使用空数组作为 dependencies 数组。

useEffect(() => {
   // This code runs once
}, [])Code language: JavaScript (javascript)

在实践中,您使用这种模式在组件的初始渲染期间运行函数。例如,您可以在组件挂载时仅运行一次从 API 获取数据的函数。

以下 UserList 组件通过调用 API 终结点 https://jsonplaceholder.typicode.com/users 来显示用户列表。

import React, { useEffect, useState } from 'react';

export default function UserList() {
  const [users, setUsers] = useState([]);

  const fetchUsers = async () => {
    const url = 'https://jsonplaceholder.typicode.com/users';
    const response = await fetch(url);
    const data = await response.json();
    setUsers(data);
  };

  useEffect(() => {
    fetchUsers();
  }, []);

  return (
    <div>
      <h1>User List</h1>
      <ul>
        {users.map((user) => (
          <li key={user.id}>{user.name}</li>
        ))}
      </ul>
    </div>
  );
}Code language: JavaScript (javascript)

每当依赖项更改时运行效果

要运行某些值更改时的函数,您可以在 dependencies 数组中指定这些值。

以下 CounterTitle 组件利用 useEffect() hook 在 count 状态变量更改时更新文档标题。

import { useState, useEffect } from 'react';

const CounterTitle = () => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `Count: ${count}`;
  }, [count]);

  return (
    <div>
      <h1>Current count: {count}</h1>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
};

export default CounterTitle;Code language: JavaScript (javascript)

每次重新渲染后运行效果

要在初始渲染期间和每次重新渲染后运行函数,您只需将 setup 函数传递给 useEffect() 函数,并跳过 dependencies 数组。

例如,您可以使用 useEffect() 函数在组件渲染时以及每次重新渲染时记录一条消息。

import React, { useState, useEffect } from 'react';

const Counter = () => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log('Component rendered or rerendered');
  });

  return (
    <div>
      <h1>Current count: {count}</h1>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
};

export default Counter;Code language: JavaScript (javascript)

运行清理函数

以下 WindowDimension 组件侦听窗口大小调整事件,并根据窗口的大小更新宽度和高度状态变量。

import { useState, useEffect } from 'react';

function WindowDimension() {
  const [width, setWidth] = useState(window.innerWidth);
  const [height, setHeight] = useState(window.innerHeight);

  useEffect(() => {
    // Define the handler function that updates the state with the window's width
    const handleResize = () => {
      setWidth(window.innerWidth);
      setHeight(window.innerHeight);
    };

    // Add the event listener for window resize
    window.addEventListener('resize', handleResize);

    // Cleanup function: Remove the event listener when the component unmounts
    return () => {
      window.removeEventListener('resize', handleResize);
    };
  }, []);

  return (
    <div>
      <p>
        Current dimension: {width}x{height}px
      </p>
    </div>
  );
}

export default WindowDimension;Code language: JavaScript (javascript)

工作原理。

首先,定义 handleResize() 函数来根据窗口的 innerWidthinnerHeight 更新宽度和高度状态变量。

const handleResize = () => {
   setWidth(window.innerWidth);
   setHeight(window.innerHeight);
};Code language: JavaScript (javascript)

其次,使用 handleResize() 函数注册大小调整事件的事件侦听器。

 window.addEventListener('resize', handleResize);Code language: JavaScript (javascript)

第三,从 useEffect 返回一个清理函数,该函数使用 window.removeEventListener 方法删除大小调整事件侦听器。

return () => {
      window.removeEventListener('resize', handleResize);
};Code language: JavaScript (javascript)

这可以防止组件在从 DOM 中删除后调用 handleResize 函数,这可能会导致内存泄漏和意外行为。

总结

  • 使用 useEffect(setup) 在组件渲染和重新渲染时运行 setup 函数。
  • 使用 useEffect(setup,[]) 在初始渲染期间仅运行一次 setup 函数。
  • 使用 useEffect(setup, [dependencies]) 在组件渲染时以及每次 dependencies 数组中的项目更改时运行 setup 函数。
本教程对您有帮助吗?