菜单
×
   ❮     
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 Hook


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

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

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

useEffect(<函数>, <依赖项>)


让我们以计时器为例。

示例

使用 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. Props 或 state 值

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 />);

运行示例 »

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



×

联系销售

如果您想将 W3Schools 服务用于教育机构、团队或企业,请发送电子邮件给我们
sales@w3schools.com

报告错误

如果您想报告错误,或想提出建议,请发送电子邮件给我们
help@w3schools.com

W3Schools 经过优化,旨在方便学习和培训。示例可能经过简化,以提高阅读和学习体验。教程、参考资料和示例会不断审查,以避免错误,但我们无法保证所有内容的完全正确性。使用 W3Schools 即表示您已阅读并接受我们的使用条款Cookie 和隐私政策

版权所有 1999-2024 Refsnes Data。保留所有权利。W3Schools 由 W3.CSS 提供支持