useEffect
useEffect(didUpdate,[deps]);
useEffect是页面真正渲染完成之后,执行的一个回调。
useEffect 会在浏览器绘制后延迟执行,但会保证在任何新的渲染前执行。在开始新的更新前,React 总会先清除上一轮渲染的 effect。
与 componentDidMount、componentDidUpdate 不同的是,传给 useEffect 的函数会在浏览器完成布局与绘制之后,在一个延迟事件中被调用。这使得它适用于许多常见的副作用场景,比如设置订阅和事件处理等情况,因为绝大多数操作不应阻塞浏览器对屏幕的更新。
useLayoutEffect
其函数签名与 useEffect
相同,但它会在所有的 DOM 变更之后同步调用 effect。可以使用它来读取 DOM 布局并同步触发重渲染。在浏览器执行绘制之前,useLayoutEffect
内部的更新计划将被同步刷新。
const dom = document.createElement('h1');
dom.innerText = 'Hello World';
dom.setAttribute('id', 'div');
const start = Date.now();
document.body.appendChild(dom);
const div = document.getElementById('div');
console.log(div);
Promise.resolve(() => {
while (Date.now() - start < 10000) {}
});
dom.innerText = Math.random() * 10;
const dom = document.createElement('h1');
dom.innerText = 'Hello World';
dom.setAttribute('id', 'div');
const start = Date.now();
document.body.appendChild(dom);
const div = document.getElementById('div');
console.log(div)
while (Date.now() - start < 10000) {}
dom.innerText = Math.random() * 10;
useLayoutEffect
里面的回调会阻止渲染。是一个同步的过程。useEffect
是一个异步的过程。
所以95%以上场景,用useEffect
就能解决问题了。
可以使用它来读取 DOM 布局并同步触发重渲染。在浏览器执行绘制之前,useLayoutEffect 内部的更新计划将被同步刷新。