useEffect
引用官方
使用 useEffect 完成副作用操作。赋值给 useEffect 的函数会在组件渲染到屏幕之后执行。你可以把 effect 看作从 React 的纯函数式世界通往命令式世界的逃生通道。
useLayoutEffect
引用官方
其函数签名与 useEffect 相同,但它会在所有的 DOM 变更之后同步调用 effect。可以使用它来读取 DOM 布局并同步触发重渲染。在浏览器执行绘制之前,useLayoutEffect 内部的更新计划将被同步刷新。
简单来说就是:
useLayoutEffect:是在所有DOM变更之后浏览器渲染之前调用,既同步调用
useEffect:是在组件渲染到屏幕之后执行,既异步调用
useEffect
import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
const BlinkyRender = () => {
const [value, setValue] = useState(0);
useEffect(() => {
if (value === 0) {
setValue(10 + Math.random() * 200);
}
}, [value]);
console.log("render", value);
return (
<div onClick={() => setValue(0)}>value: {value}</div>
);
};
ReactDOM.render(
<BlinkyRender />,
document.querySelector("#root")
);
点击div的时候,先是将value state设置为0,触发渲染,然后执行useEffect在设置为一个随机数,再次触发渲染,明显看到会有闪烁,虽然短暂但是不友好
执行步骤:
1、click setState (value)
2、虚拟 DOM 设置到真实 DOM 上
3、渲染
4、执行useEffect回调
useLayoutEffect
import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
const BlinkyRender = () => {
const [value, setValue] = useState(0);
useLayoutEffect(() => {
if (value === 0) {
setValue(10 + Math.random() * 200);
}
}, [value]);
console.log("render", value);
return (
<div onClick={() => setValue(0)}>value: {value}</div>
);
};
ReactDOM.render(
<BlinkyRender />,
document.querySelector("#root")
);
点击div的时候,先是将value设置为0,然后在设置为一个随机数,最后渲染
执行步骤:
1、click setState (value)
2、虚拟 DOM 设置到真实 DOM 上
3、执行useLayEffect回调
4、渲染