文章概括
本文主要讲的是UseEffect的用法,也会讲解一下相关的原理,但是不会涉及到类组件跟函数组件的区别。
开篇废话
众所周知,React的组件为类组件以及函数组件,现在的React推荐使用的是函数组件,所以我们在开发的时候也很少使用类组件,而是函数组件,而在16.8之后,React也添加了一些hook,就是我们所说的钩子函数,钩子函数的重要性,就跟我们在类组件中的生命周期一样重要,所以一定要学会这几个常用的钩子函数。
在函数组件中,有一个很关键的概念,叫做副作用,在官网上称之为Effect
Effect 允许你指定由渲染本身,而不是特定事件引起的副作用。
Effect 在 React 中是专有定义------由渲染引起的副作用。为了指代更广泛的编程概念,也可以将其称为"副作用(side effect)"。
官网上解释的也很清楚,也就是渲染引起的副作用,大概可以理解为,当我们渲染完一次页面之后,就会调用一次我们定义好的副作用,接着就会走一遍我们的代码,新手可以在那时理解为回调函数~但是请注意,并非React建议使用钩子函数,因为也提醒到了。
不要随意在你的组件中使用 Effect。记住,Effect 通常用于暂时"跳出" React 代码并与一些 外部 系统进行同步。这包括浏览器 API、第三方小部件,以及网络等等。如果你想用 Effect 仅根据其他状态调整某些状态,那么 你可能不需要 Effect。
之所以这么说,是因为
但是,钩子的灵活性太大,初学者不太容易理解。很多人一知半解,很容易写出混乱不堪、无法维护的代码。那就不如使用类组件了。因为类组件有很多强制的语法约束,不容易搞乱
UseEffect
老规矩,贴一些关于React上的描述先。
useEffect 是一个 React Hook,它允许你 将组件与外部系统同步。
有些组件需要与外部系统同步。例如,你可能希望根据 React state 控制非 React 组件、设置服务器连接或在组件出现在屏幕上时发送分析日志。Effects 会在渲染后运行一些代码,以便可以将组件与 React 之外的某些系统同步。
按照我粗鄙的理解,也就是当我们的页面渲染之后,他会做一些操作。 useEffect有两个参数,为
javascript
useEffect(setup, dependencies?)
setup:处理 Effect 的函数。setup 函数选择性返回一个 清理(cleanup) 函数。当组件被添加到 DOM 的时候,React 将运行 setup 函数。在每次依赖项变更重新渲染后,React 将首先使用旧值运行 cleanup 函数(如果你提供了该函数),然后使用新值运行 setup 函数。在组件从 DOM 中移除后,React 将最后一次运行 cleanup 函数。
可选 dependencies:setup 代码中引用的所有响应式值的列表。响应式值包括 props、state 以及所有直接在组件内部声明的变量和函数。如果你的代码检查工具 配置了 React,那么它将验证是否每个响应式值都被正确地指定为一个依赖项。依赖项列表的元素数量必须是固定的,并且必须像 [dep1, dep2, dep3] 这样内联编写。React 将使用 Object.is 来比较每个依赖项和它先前的值。如果省略此参数,则在每次重新渲染组件之后,将重新运行 Effect 函数。
总结下来,对于第一个参数,需要返回一个函数,而函数可以返回一个叫做cleaup的函数,且cleanup的函数,是在页面卸载的时候,React会最后一次运行leanup。
对于第二个参数,是一个可选的参数,并且是一个数组,主要作用是控制什么时候运行我们的useEffect,比如在state中定义了一个变量A,当A变化的时候,我们定义的函数就会调用。
例子
接下来举一个很简单的例子
javascript
import { useEffect, useState } from "react";
function UseEffectComponent() {
const [A, setA] = useState(0);
const handleClick = () => {
console.log("点击了!");
setA(A + 1);
};
useEffect(() => {
console.log("页面被渲染了!");
return () => {
console.log("useEffect的返回函数");
};
}, []);
return (
<>
<button
onClick={() =>
{
handleClick();
}}
>
点击按钮
</button>
</>
);
}
export default UseEffectComponent;
查看效果图后发现,"页面被渲染了!"打印出来了两次,且"useEffect的返回函数"也执行了一次,而由于我们在useEffect中并没有设置执行依赖项,所以就只有一次执行。
备注下,"页面被渲染了"之所以打印出来两次,是因为React在dev的情况下,会多做一次校验.所以会打印出来两次。
接下来,我们再将"A"设置在useEffect的"dependencies"数组参数中,既
javascript
useEffect(() => {
console.log("页面被渲染了!");
return () => {
console.log("useEffect的返回函数");
};
}, [A]);
此时,效果如下
当state发生变化的时候,副作用就会被调用,此时就会调用到我们设置好的函数。
但是我们也发现了,我们useEffect的返回函数,也被调用了,这样子页面刷新,调用我们的useEffect的时候,都会调用一次我们的返回函数,所以无法做到页面卸载之前"最后一次调用"的效果,这个是需要注意的
最后的总结
如果,想要在页面第一次渲染之后初始化我们的数据,比如获取API的时候,就可以将useEffect的"dependencies"设置为一个空的数组
如果非必要,最好使用多个useEffect,这样子逻辑比较清晰,别人很容易看.
呜呜呜,个人博客公众号求关注
公众号主要写前端的,多谢各位大佬们关注