useEffect

  1. useEffect(didUpdate,[deps]);

useEffect是页面真正渲染完成之后,执行的一个回调。
useEffect 会在浏览器绘制后延迟执行,但会保证在任何新的渲染前执行。在开始新的更新前,React 总会先清除上一轮渲染的 effect。

与 componentDidMount、componentDidUpdate 不同的是,传给 useEffect 的函数会在浏览器完成布局与绘制之后,在一个延迟事件中被调用。这使得它适用于许多常见的副作用场景,比如设置订阅和事件处理等情况,因为绝大多数操作不应阻塞浏览器对屏幕的更新。

useLayoutEffect

其函数签名与 useEffect 相同,但它会在所有的 DOM 变更之后同步调用 effect。可以使用它来读取 DOM 布局并同步触发重渲染。在浏览器执行绘制之前,useLayoutEffect 内部的更新计划将被同步刷新。

  1. const dom = document.createElement('h1');
  2. dom.innerText = 'Hello World';
  3. dom.setAttribute('id', 'div');
  4. const start = Date.now();
  5. document.body.appendChild(dom);
  6. const div = document.getElementById('div');
  7. console.log(div);
  8. Promise.resolve(() => {
  9. while (Date.now() - start < 10000) {}
  10. });
  11. dom.innerText = Math.random() * 10;
  1. const dom = document.createElement('h1');
  2. dom.innerText = 'Hello World';
  3. dom.setAttribute('id', 'div');
  4. const start = Date.now();
  5. document.body.appendChild(dom);
  6. const div = document.getElementById('div');
  7. console.log(div)
  8. while (Date.now() - start < 10000) {}
  9. dom.innerText = Math.random() * 10;

useLayoutEffect里面的回调会阻止渲染。是一个同步的过程。useEffect是一个异步的过程。

所以95%以上场景,用useEffect就能解决问题了。

可以使用它来读取 DOM 布局并同步触发重渲染。在浏览器执行绘制之前,useLayoutEffect 内部的更新计划将被同步刷新。