值得做的事情
- 去学useLayoutEffect
useLayoutEffect 是 useEffect 的一个版本,在浏览器重新绘制屏幕之前触发。
- useEffect 在 依赖项变化后当前的Commit 阶段之后异步执行。它是异步执行的,不会阻塞浏览器绘制过程。
- 由于 useEffect 是在组件渲染到屏幕之后运行的,所以它不会影响组件的渲染性能。
useEffect 适用于不需要立即反映在屏幕上的操作,如发送网络请求、设置订阅以及其他不会对 DOM 产生直接、同步影响的副作用。
useLayoutEffect
useLayoutEffect 在 当前Commit 阶段同步执行,但在浏览器进行任何绘制之前触发。它是同步执行的,会阻塞浏览器的绘制。
- 由于 useLayoutEffect 在 DOM 更新完成后立即执行,但在浏览器绘制之前,它适用于需要同步读取或更新 DOM 的操作,以避免可能出现的闪烁问题。
- useLayoutEffect 适用于那些需要确保 DOM 更新后立即同步执行的操作,如布局调整、获取 DOM 节点尺寸或位置等。
清理函数
执行时机是每次卸载(组件隐藏)或者依赖项发生变化的时候也会执行!!并且会在回调函数之前执行,也就是会先执行清理函数,使用的是上一次的状态,在使用effect回调,使用的是现在的状态。这优化了性能封装hook的时机?
当你需要“走出 React 之外”或者当你的使用场景没有更好的内置解决方案时,你可以使用它们。如果你发现自己经常需要手动编写 Effect,那么这通常表明你需要为组件所依赖的通用行为提取一些 自定义 Hook。
好像意思是把effect放进usehook里处理?使用 Effect 请求数据
```javascript import { useState, useEffect } from ‘react’; import { fetchBio } from ‘./api.js’;
export default function Page() { const [person, setPerson] = useState(‘Alice’); const [bio, setBio] = useState(null);
useEffect(() => { let ignore = false; setBio(null); fetchBio(person).then(result => { if (!ignore) { setBio(result); } }); return () => { ignore = true; }; }, [person]);
```
这个做法是为了防止组件卸载了之后,状态由于请求时间慢而才执行。
使用 ignore 变量和清理函数的目的是为了安全地管理异步操作,确保只有在组件仍然挂载时才更新状态,从而避免不必要的渲染和性能问题
Effect 的响应式依赖项
Effect 代码中使用的每个 响应式值 都必须声明为依赖项。
响应式值 包括 props 和直接在组件内声明的所有变量和函数。你不能将它们从依赖项中移除。如果你试图省略它们,并且你的代码检查工具针对 React 进行了正确的配置,那么代码检查工具会将它标记为需要修复的错误:
Effect 依赖于在渲染期间创建的对象或函数
总结:避免使用对象和函数作为依赖项