Menu
×
   ❮     
HTML CSS JAVASCRIPT SQL PYTHON JAVA PHP HOW TO W3.CSS C C++ C# BOOTSTRAP REACT MYSQL JQUERY EXCEL XML DJANGO NUMPY PANDAS NODEJS R TYPESCRIPT ANGULAR GIT POSTGRESQL MONGODB ASP AI GO KOTLIN SASS VUE DSA GEN AI SCIPY AWS CYBERSECURITY DATA SCIENCE
     ❯   

React useEffect Hooks


The useEffect Hook 允许你在组件中执行副作用。

一些副作用的例子包括:获取数据、直接更新 DOM 和计时器。

useEffect 接受两个参数。第二个参数是可选的。

useEffect(<function>, <dependency>)


让我们以计时器为例。

示例

使用 setTimeout() 在初始渲染后计算 1 秒

import { useState, useEffect } from "react";
import ReactDOM from "react-dom/client";

function Timer() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    setTimeout(() => {
      setCount((count) => count + 1);
    }, 1000);
  });

  return <h1>I've rendered {count} times!</h1>;
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Timer />);

运行示例 »

但是等等!即使它应该只计算一次,它也一直在计算!

useEffect 在每次渲染时都会运行。这意味着当计数发生变化时,会发生渲染,然后触发另一个效果。

这不是我们想要的。有几种方法可以控制副作用何时运行。

我们应该始终包含第二个参数,它接受一个数组。我们可以选择性地将依赖项传递给此数组中的 useEffect

示例

1. 没有传递依赖项

useEffect(() => {
  //Runs on every render
});

示例

2. 一个空数组

useEffect(() => {
  //Runs only on the first render
}, []);

示例

3. 属性或状态值

useEffect(() => {
  //Runs on the first render
  //And any time any dependency value changes
}, [prop, state]);

所以,为了解决这个问题,让我们只在初始渲染时运行此效果。

示例

仅在初始渲染时运行效果

import { useState, useEffect } from "react";
import ReactDOM from "react-dom/client";

function Timer() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    setTimeout(() => {
      setCount((count) => count + 1);
    }, 1000);
  }, []); // <- add empty brackets here

  return <h1>I've rendered {count} times!</h1>;
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Timer />);

运行示例 »

示例

这是一个依赖于变量的 useEffect Hook 的示例。如果 count 变量更新,则效果将再次运行

import { useState, useEffect } from "react";
import ReactDOM from "react-dom/client";

function Counter() {
  const [count, setCount] = useState(0);
  const [calculation, setCalculation] = useState(0);

  useEffect(() => {
    setCalculation(() => count * 2);
  }, [count]); // <- add the count variable here

  return (
    <>
      <p>Count: {count}</p>
      <button onClick={() => setCount((c) => c + 1)}>+</button>
      <p>Calculation: {calculation}</p>
    </>
  );
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Counter />);

运行示例 »

如果有多个依赖项,则应将其包含在 useEffect 依赖项数组中。


w3schools CERTIFIED . 2022

获得认证!

完成 React 模块,完成练习,参加考试并获得 w3schools 认证!!

$95 报名

效果清理

一些效果需要清理以减少内存泄漏。

超时、订阅、事件监听器以及不再需要的其他效果应该被释放。

我们通过在 useEffect Hook 的末尾包含一个返回函数来做到这一点。

示例

useEffect Hook 的末尾清理计时器

import { useState, useEffect } from "react";
import ReactDOM from "react-dom/client";

function Timer() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    let timer = setTimeout(() => {
    setCount((count) => count + 1);
  }, 1000);

  return () => clearTimeout(timer)
  }, []);

  return <h1>I've rendered {count} times!</h1>;
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Timer />);

运行示例 »

注意:为了清除计时器,我们必须为其命名。



×

Contact Sales

If you want to use W3Schools services as an educational institution, team or enterprise, send us an e-mail:
[email protected]

Report Error

If you want to report an error, or if you want to make a suggestion, send us an e-mail:
[email protected]

W3Schools is optimized for learning and training. Examples might be simplified to improve reading and learning. Tutorials, references, and examples are constantly reviewed to avoid errors, but we cannot warrant full correctness of all content. While using W3Schools, you agree to have read and accepted our terms of use, cookie and privacy policy.

Copyright 1999-2024 by Refsnes Data. All Rights Reserved. W3Schools is Powered by W3.CSS.