IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 深入学习React Hook——useEffect -> 正文阅读

[JavaScript知识库]深入学习React Hook——useEffect

Hook使用规则

  • 只能在函数的最外层调用Hook,不能在循环、条件判断或子函数中调用。
  • 只能在React函数组件或自定义Hook中调用Hook,不可在其他JavaScript函数中使用。

useEffect一句话简介

useEffect相当于componentDidMount、componentDidUpdate、componentWillUnmount这三个生命周期方法的组合。

参数

参数1:函数,即effect

  • 函数体:执行各种副作用操作,如网络请求、添加订阅、添加计时器等。
  • 函数返回值:执行取消订阅、取消计时器等清理。

参数2:依赖项数组

  • 在依赖项数组中的effect需要引用值会改变外部变量,当它们的值改变时:
    1. 挂载阶段,effect函数体会在组件挂载后延迟一段时间被调用,相当于componentDidMount。
    2. 更新阶段,effect函数体会在组件更新后延迟一段时间被调用,相当于componentDidUpdate。
    3. 卸载阶段,effect函数返回值会在组件将要卸载前被调用,相当于componentWillUnmount。
  • 如果依赖项是空数组:
    1. 挂载阶段,effect函数体会在组件挂载后后延迟一段时间被调用,componentDidMount
    2. 更新阶段,effect函数体不会被调用,相当于componentDidUpdate。
    3. 卸载阶段,effect函数返回值会在组件将要卸载前被调用,相当于componentWillUnmount。
  • 如果effect使用的外部变量不在依赖项中,这些变量的值不会更新。
  • 值不会改变的外部变量不要加在依赖项中。例如React保证useState的更新函数不会改变,它们无需加入依赖数组。

如何区分变量是否会改变?

存放数据的变量是否会改变得看具体的代码才能确定;存放函数的变量是否会改变的规律总结如下:

  • useState的更新函数不会改变。
  • useCallback的返回值函数在依赖项不变的情况下不会改变。
  • 函数组件中的匿名函数和命名函数都会改变。

案例

import React, { memo, useCallback, useState } from "react";

type Style = {
  color: string;
  background: string;
};

const Show: React.FC<{ state: Style }> = (props) => {
  const { color, background } = props.state;
  console.log("Show");
  return (
    <div style={{ color, background }}>
      测试文字,文字的颜色和背景色可以切换!
    </div>
  );
};

const HandleColor: React.FC<{
  setState: React.Dispatch<React.SetStateAction<Style>>;
}> = memo((props) => {
  const { setState } = props;
  console.log("HandleColor");
  return (
    <button
      onClick={() =>
        // 更新函数和数据没放在一起,不易维护
        setState((preState) =>
          preState.color === "red"
            ? { ...preState, color: "blue" }
            : { ...preState, color: "red" }
        )
      }
    >
      点我改变颜色
    </button>
  );
});

const HandleBackground1: React.FC<{
  setBackground: () => void;
}> = memo((props) => {
  const { setBackground } = props;
  console.log("HandleBackground-1");
  return <button onClick={() => setBackground()}>点我改变背景</button>;
});

const HandleBackground2: React.FC<{
  setBackground: () => void;
}> = memo((props) => {
  const { setBackground } = props;
  console.log("HandleBackground-2");
  return <button onClick={() => setBackground()}>点我改变背景</button>;
});

const App = () => {
  const [state, setState] = useState<Style>({
    color: "red",
    background: "black"
  });
  console.log("渲染了App");
  const setBackground = useCallback(
    () =>
      setState((preState) =>
        preState.background === "black"
          ? { ...preState, background: "gray" }
          : { ...preState, background: "black" }
      ),
    []
  );
  const setBackground2 = () =>
    setState((preState) =>
      preState.background === "black"
        ? { ...preState, background: "gray" }
        : { ...preState, background: "black" }
    )
  return (
    <>
      <Show state={state} />
      <HandleColor setState={setState} />
      <HandleBackground1 setBackground={setBackground} />
      <HandleBackground2 setBackground={setBackground2} />
    </>
  );
};

export default App;

在线体验
仔细看console.log打印的日志,点击HandleBackground1按钮时,只会提示“HandleBackground-2”,这说明HandleBackground2组件收到的props发生了改变,而HandleBackground1组件收到的props未发生改变。

建议

  • 在涉及多个业务逻辑的复杂组件中,建议按业务逻辑拆分useEffect,这样可以提高代码可维护性。
    例如:某组件需要向2个API接口分别请求数据,此时就应该分开写在2个useEffect中,而不应集中写在一个useEffect中。这样以后遇到某个API接口有变动需要改代码时,分开写useEffect比集中写会更方便维护。
  • 集中在一起的useEffect与按业务逻辑拆成多个的useEffect相比运行效率几乎没差别,拆分useEffect不会导致额外的渲染。
  • 条件判断不能写在effect函数外面,必须写在effect函数内部。

代码片段

2022-04-25_15-35.png

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-27 11:15:01  更:2022-04-27 11:15:14 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 1:07:54-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码