1.useEffect
import React, { useState, useEffect } from "react";
import { Button } from 'antd';
import './Demo.less';
/*
useEffect:在函数组件中,使用生命周期函数
useEffect(callback):没设置依赖
+ 第一次渲染完毕后,执行callback,等价于 componentDidMount
+ 在组件每一次更新完毕后,也会执行callback,等价于 componentDidUpdate
useEffect(callback,[]):设置了,但是无依赖
+ 只有第一次渲染完毕后,才会执行callback,每一次视图更新完毕后,callback不再执行
+ 类似于 componentDidMount
useEffect(callback,[依赖的状态(多个状态)]):
+ 第一次渲染完毕会执行callback
+ 当依赖的状态值(或者多个依赖状态中的一个)发生改变,也会触发callback执行
+ 但是依赖的状态如果没有变化,在组件更新的时候,callback是不会执行的
useEffect(()=>{
return ()=>{
// 返回的小函数,会在组件释放的时候执行
// 如果组件更新,会把上一次返回的小函数执行「可以“理解为”上一次渲染的组件释放了」
};
});
*/
const Demo = function Demo() {
let [num, setNum] = useState(0),
[x, setX] = useState(100);
useEffect(() => {
// 获取最新的状态值
console.log('@1', num);
});
useEffect(() => {
console.log('@2', num);
}, []);
useEffect(() => {
console.log('@3', num);
}, [num]);
useEffect(() => {
return () => {
// 获取的是上一次的状态值
console.log('@4', num);
};
}); // 这里传[num]和不传都一样
const handle = () => {
setNum(num + 1);
};
return
{num}
;
};
export default Demo;
执行原理
2.useEffect和useLayoutEffect的细节
①不能把useEffect放在条件判断中,可以把条件判断放在useEffect的回调函数中
②useEffect的回调函数要么不返回值,要么只能返回一个函数
③经过async修饰之后,即使不写返回,默认返回Promise实例
import React, { useState, useEffect } from "react";
import { Button } from 'antd';
import './Demo.less';
// 模拟从服务器异步获取数据
const queryData = () => {
return new Promise(resolve => {
setTimeout(() => {
resolve([10, 20, 30]);
}, 1000);
});
};
const Demo = function Demo() {
let [num, setNum] = useState(0);
/* // useEffect必须在函数的最外层上下文中调用,不能把其嵌入到条件判断、循环等操作语句中
if (num > 5) {
useEffect(() => {
console.log('OK');
});
} */
useEffect(() => {
if (num > 5) {
console.log('OK');
}
}, [num]);
// 第一次渲染完毕后,从服务器异步获取数据
/* // useEffect如果设置返回值,则返回值必须是一个函数「代表组件销毁时触发」;下面案例中,callback经过async的修饰,返回的是一个promise实例,不符合要求!!
useEffect(async () => {
let data = await queryData();
console.log('成功:', data);
}, []); */
/* useEffect(() => {
queryData()
.then(data => {
console.log('成功:', data);
});
}, []); */
useEffect(() => {
const next = async () => {
let data = await queryData();
console.log('成功:', data);
};
next();
}, []);
const handle = () => {
setNum(num + 1);
};
return
{num}
;
};
export default Demo;
3.useEffect与useLayoutEffect的区别
useLayoutEffect先于useEffect
两者都可以获取dom,
import React, { useState, useEffect, useLayoutEffect } from "react";
import { Button } from 'antd';
import './Demo.less';
const Demo = function Demo() {
// console.log('RENDER');
let [num, setNum] = useState(0);
/* useLayoutEffect(() => {
if (num === 0) {
setNum(10);
}
}, [num]); */
/*
useLayoutEffect会阻塞浏览器渲染真实DOM,优先执行Effect链表中的callback;
useEffect不会阻塞浏览器渲染真实DOM,在渲染真实DOM的同时,去执行Effect链表中的callback;
+ useLayoutEffect设置的callback要优先于useEffect去执行!!
+ 在两者设置的callback中,依然可以获取DOM元素「原因:真实DOM对象已经创建了,区别只是浏览器是否渲染」
+ 如果在callback函数中又修改了状态值「视图又要更新」
+ useEffect:浏览器肯定是把第一次的真实已经绘制了,再去渲染第二次真实DOM
+ useLayoutEffect:浏览器是把两次真实DOM的渲染,合并在一起渲染的
视图更新的步骤:
第一步:基于babel-preset-react-app把JSX编译为createElement格式
第二步:把createElement执行,创建出virtualDOM
第三步:基于root.render方法把virtualDOM变为真实DOM对象「DOM-DIFF」
useLayoutEffect阻塞第四步操作,先去执行Effect链表中的方法「同步操作」
useEffect第四步操作和Effect链表中的方法执行,是同时进行的「异步操作」
第四步:浏览器渲染和绘制真实DOM对象
*/
useLayoutEffect(() => {
console.log('useLayoutEffect'); //第一个输出
}, [num]);
useEffect(() => {
console.log('useEffect'); //第二个输出
}, [num]);
return
{num}
;
};
export default Demo;
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
相关推荐: 【机器学习】pytorch安装——环境配置(极简教程)🥑 Welcome to Aedream同学 ‘s blog! 🥑
🥑 Welcome to Aedream同学 ‘s blog! 🥑 文章目录 省流总结 新建环境 确定显卡型号 安装显卡驱动 安装pytorch 国内镜像下载 本地下载 验证安装成功 最近重新配置环境,简单记录一下。最近chatgpt等大语言模型和ai绘图火热…