第六章 React Hooks之useEffect

2023-12-14 00:11:02

一、专栏介绍?????

欢迎加入本专栏!本专栏将引领您快速上手React,让我们一起放弃放弃的念头,开始学习之旅吧!我们将从搭建React项目开始,逐步深入讲解最核心的hooks,以及React路由、请求、组件封装以及UI(Ant Design)框架的使用。让我们一起掌握React,开启前端开发的全新篇章。

二、useEffect是什么?????

useEffect是React中的一个Hook,用于在函数组件中执行副作用。副作用是指那些不直接与组件渲染结果相关的操作,例如访问外部API、修改DOM、订阅事件等。

具体来说,useEffect可以看作是componentDidMount、componentDidUpdate和componentWillUnmount这几个生命周期方法的组合。它允许你在组件渲染完毕后,再执行一些回调函数来处理副作用。在函数式编程中,函数应该是纯函数,也就是说,函数的输出只取决于它的输入,而不与外部环境产生任何交互或副作用。因此,useEffect在处理那些需要与外部环境交互的副作用时非常有用。

三、使用useEffect?????

 useEffect(() => {
    /** 执行逻辑 */
  }, []);

useEffect是一个React Hook,它允许在函数组件中执行副作用操作。它接收两个参数:第一个参数是一个函数,用于编写逻辑代码;第二个参数是可选的,用于指定依赖数组。当依赖数组中的变量发生变化时,逻辑处理函数将被执行,这通常意味着组件的DOM将重新渲染。

通过使用useEffect,我们可以在组件渲染后执行重要的副作用操作,例如与外部API进行交互、修改DOM或订阅事件等。此外,useEffect可以替代函数组件中的componentDidMount、componentDidUpdate和componentWillUnmount等生命周期方法,使代码更加简洁和可读。

import React, { useEffect } from 'react';
import './App.css';
import { useImmer } from 'use-immer';

function Example() {
  // 定义用户的类型
  type UserType = {
    name: string;
    password: string;
  };

  const [loginData, setLoginData] = useImmer<UserType>({
    name: '',
    password: '',
  });

  const [loginLoading, setLoginLoading] = useImmer<boolean>(false);

  useEffect(() => {
    console.log('👉👉👉-----------------每一次DOM更新完成后都会被执行一次');
  });

  useEffect(() => {
    console.log('👉👉👉-----------------只会在初始化完成后执行一次');
  }, []);

  useEffect(() => {
    console.log('👉👉👉-----------------只会在初始化完成后以及loginData变化后执行一次');
  }, [loginData]);

  useEffect(() => {
    console.log('👉👉👉-----------------只会在初始化完成后以及loginData.name变化后执行一次');
  }, [loginData.name]);

  useEffect(() => {
    console.log(
      '👉👉👉-----------------同时监听多个变量,初始化完成后以及loginData或loginLoading值发生变化时'
    );
  }, [loginData, loginLoading]);

  useEffect(() => {
    if (loginLoading) {
      console.log('👉👉👉-----------------因为加了条件语句,只会在loginLoading为true时才会被执行');
    }
  }, [loginLoading]);

  return (
    <div>
      {loginLoading ? (
        <div>登录中……</div>
      ) : (
        <div>
          <form>
            <div>
              <p>用户名:</p>
              <input
                type="text"
                onChange={(e) =>
                  setLoginData((prev) => {
                    prev.name = e.target.value;
                  })
                }
                name="name"
              />
            </div>
            <div>
              <p>密码:</p>
              <input
                type="password"
                onChange={(e) =>
                  setLoginData((prev) => {
                    prev.password = e.target.value;
                  })
                }
                name="password"
              />
            </div>
            <br />
          </form>
          <button
            onClick={() => {
              setLoginLoading(true);
              // 这里获取到用户的输入信息以后调用接口,继续编写其他的逻辑
              console.log('👉👉👉-----------------', loginData);
              setTimeout(function () {
                setLoginLoading(false);
              }, 2000);
            }}
          >
            登录
          </button>
        </div>
      )}
    </div>
  );
}

export default Example;

四、小案例?????

案例中使用了useRef Hook,这个使用过vue的小伙伴一定不会陌生,Ref可以让我们更方便的获取到DOM元素。下一篇博文会对useRef进行讲解

import React, { useEffect, useRef, useState } from 'react';
import './App.css';

function Example() {
  const [isOpen, setIsOpen] = useState(false);

  const ref = useRef(null);

  useEffect(() => {
    if (!isOpen) {
      return;
    }
    const dialog: HTMLDialogElement = ref.current!;
    dialog.showModal();
    return () => {
      dialog.close();
    };
  }, [isOpen]);

  return (
    <div>
      <dialog ref={ref}>
        <button
          onClick={() => {
            const dialog: HTMLDialogElement = ref.current!;
            setIsOpen(false);
            dialog.close();
          }}
        >
          关闭模态框
        </button>
      </dialog>
      <button onClick={() => setIsOpen(true)}>打开模态框</button>
    </div>
  );
}

export default Example;

五、useEffect同步异步?????

useEffect中不能直接使用async,因为上面说过了,它的第一个参数接收一个函数,它可以不返回任何东西,如果返回也只能返回一个函数。而async返回的是一个Promise。

错误的写法

useEffect(async () => {
const data = await getData();
console.log('👉👉👉-----------------', data);
}, []);

useEffect支持的写法

useEffect(() => {
console.log('👉👉👉-----------------', 123);
}, []);

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

5.1、解决办法一(立即执行函数)?👇👇

(function(){
  console.log('立即调用函数表达式')
})()
import React, { useEffect } from 'react';

function Example() {
  const getData = () => {
    return new Promise((resolve) => {
      resolve({
        name: '张三',
        age: 27,
      });
    });
  };

  useEffect(() => {
    (async function IIFEGetData() {
      const data = await getData();
      console.log('👉👉👉-----------------', data);
    })();
  }, []);

  return <></>;
}

export default Example;

5.2、解决办法二?👇👇

import React, { useEffect } from 'react';

function Example() {
  const getData = () => {
    return new Promise((resolve) => {
      resolve({
        name: '张三',
        age: 27,
      });
    });
  };

  const fetch = async () => {
    const data = await getData();
    console.log('👉👉👉-----------------', data);
    return data;
  };

  useEffect(() => {
    // 这种办法呢我们只能在fetch内部去接着处理逻辑
    fetch();
  }, []);

  return <></>;
}

export default Example;

六、总结???

useEffect就有点类型于Vue中的学习React需要掌握useEffect。useEffect是React中的一个非常重要的Hook,它允许在函数组件中执行副作用操作。在开发中,useEffect非常重要,因为它可以帮助我们处理许多常见的副作用操作,例如订阅事件、修改DOM、发送网络请求等。

通过使用useEffect,我们可以将副作用代码从组件的渲染逻辑中分离出来,使其更加清晰和易于维护。此外,useEffect还可以帮助我们避免在组件卸载后忘记取消订阅事件或清除定时器等常见问题。

因此,掌握useEffect对于学习React和开发React应用程序非常重要。

我是Etc.End。如果文章对你有所帮助,能否帮我点个免费的赞和收藏😍。

9d8c73c39a7643afaa54e2e4fd70f8db.jpeg?

👇 👇 👇 👇 👇 👇 👇 👇 👇 👇 👇 👇

文章来源:https://blog.csdn.net/qq_19991931/article/details/134726913
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。