什么时候使用useEffect?

IT技术 reactjs
2021-05-21 13:15:32

我目前正在查看 useEffect 的 react 文档示例

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

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 (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

我的问题是我们可以轻松地为按钮创建一个 handleClick 函数。我们不必使用 useEffect

const handleButtonClick = () =>{
setCount(count+1)
document.title = `You clicked ${count +1} times`
}

<button onClick={handleButtonClick}/>

那么哪种方式被认为是好的做法?是否最好只使用 useEffect 来触发严格不能与主要效果一起完成的副作用(即当组件收到新props时)

3个回答

使用useEffect钩子的想法是执行需要在组件生命周期中发生的代码,而不是在特定的用户交互或 DOM 事件上。

例如,您希望设置一个计时器,该计时器在组件最初呈现时或在您的初始示例中执行代码时,在组件安装时更新文档标题,此处没有关联的用户交互

useEffect是功能组件中类组件中生命周期方法的替代方法。它可用于在组件挂载时执行操作,或为组件更新某些 prop 或状态,以及在组件即将卸载时执行代码

请参阅以下内容以获得更清晰的信息。从官方文档复制代码后,您可能错过了阅读。

使用钩子的例子

useEffect 有什么作用?

通过使用这个 Hook,你告诉 React 你的组件需要在渲染后做一些事情。React 会记住您传递的函数(我们将其称为“效果”),并在执行 DOM 更新后稍后调用它。在这个效果中,我们设置了文档标题,但我们也可以执行数据获取或调用其他一些命令式 API。

为什么在组件内部调用 useEffect?

将 useEffect 放置在组件内可以让我们直接从效果中访问计数状态变量(或任何props)。我们不需要特殊的 API 来读取它——它已经在函数范围内了。Hook 包含 JavaScript 闭包,并避免在 JavaScript 已经提供解决方案的情况下引入特定于 React 的 API。

useEffect 是否在每次渲染后运行?

是的!默认情况下,它会在第一次渲染之后和每次更新之后运行。(我们稍后将讨论如何自定义它。)与其考虑“安装”和“更新”,您可能会发现更容易认为效果发生在“渲染之后”。React 保证 DOM 在它运行效果时已经更新。

你展示了两个不同的例子,

handleButtonClickButton 1点击触发,而useEffect在每个状态改变状态触发(根据依赖数组)。

在下一个示例中,您注意到useEffect将记录每次按钮单击 ( Button 1/2),并且handleButtonClick仅在Button 2单击时记录

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

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

  useEffect(() => {
    console.log(`You rendered ${count} times`);
  }, [count]);

  const handleButtonClick = () => {
    setCount(count + 1);
    console.log(`You clicked ${count + 1} times`);
  };

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>Button 1</button>
      <button onClick={handleButtonClick}>Button 2</button>
    </div>
  );
}