useState
定义变量
const [state, setState] = useState(initialState);
state:UI的数据源setState:改变 state 的函数initialState:初始默认值
useEffect
副作用(Side Effect:是指 function 做了和本身运算返回值无关的事,如请求数据、修改全局变量,打印、数据获取、设置订阅以及手动更改 React 组件中的 DOM 都属于副作用
useEffect(() => {
// 挂载
return () => {
// 卸载
}
}, [])
通常我们用于监听addEventListener和removeEventListener
useEffect(() => {
// 依赖值得变化
}, [count])
useContent
上下文,设置全局共享数据,使所有组件可跨层级实现共享。
useContent的参数一般是由createContext的创建,通过 CountContext.Provider 包裹的组件,才能通过 useContext 获取对应的值。
const TestContext = createContext({})
<TestContext.Provider value={value}>
<Child />
</TestContext.Provider>
const Child = () => {
const value = useContext(TestContext)
console.log(value)
return null;
}
useReducer
它类似于redux功能的api
const [state, dispatch] = useReducer(reducer, initialArg, init);
state:更新后的state值dispatch:可以理解为和useState的setState一样的效果reducer:可以理解为redux的reducerinitialArg:初始值init:惰性初始化
const Component = () => {
const [count, dispatch] = useReducer((state, action)=> {
switch(action?.type){
case 'name':
return action?.payload;
default:
return state;
}
}, '小张');
return <div style={{padding: 20}}>
<div>who? {name}</div>
<Button onClick={() => dispatch({type: 'name', payload: '小王' })} >
小王
</Button>
</div>
}
useMemo
useMemo:与memo差不多,都是判断是否满足当前的限定条件来决定是否执行callback函数,而useMemo的第二个参数是一个数组,通过这个数组来判定是否更新回掉函数。
当一个页面内容非常复杂,模块非常多的时候,函数式组件会从头更新到尾,只要一处改变,所有的模块都会进行刷新,这种情况显然是没有必要的。
理想的状态是各个模块只进行自己的更新,不要相互去影响。
const Index = (list: number[]) => {
return useMemo(() => {
// 父组件的其他更新不会更新子组件
}), [])
}
useCallback
useCallback与useMemo极其类似,可以说是一模一样,唯一不同的是useMemo返回的是函数运行的结果,而useCallback返回的是函数。
这个函数是父组件传递子组件的一个函数,防止做无关的刷新,其次,这个组件必须配合memo,否则不但不会提升性能,还有可能降低性能
React.memo会通过浅比较里面的props,如果没有memo,那么使用的useCallback也就毫无意义
因为useCallback本身是需要开销的,所以反而会增加性能的消耗。
useRef
可以获取当前元素的所有属性,并且返回一个可变的ref对象,并且这个对象只有current属性
const refContainer = useRef(initialValue);
可以缓存数据,减少了不必要的更新,如过采取useState则会重新渲染。
useImperativeHandle
使用 ref 时自定义暴露给父组件的实例值
有的时候我们需要在最外层的组件上控制其他组件的方法,希望最外层的点击事件,同时执行子组件的事件
useImperativeHandle(ref, createHandle, [deps])
ref:useRef所创建的refcreateHandle:处理的函数,返回值作为暴露给父组件的 ref 对象。deps:依赖项,依赖项更改形成新的 ref 对象。
useLayoutEffect
要注意的是useLayoutEffect在 DOM 更新之后,浏览器绘制之前,这样做的好处是可以更加方便的修改 DOM,获取 DOM 信息,这样浏览器只会绘制一次,所以useLayoutEffect在useEffect之前执行
如果是useEffect的话 ,useEffect 执行在浏览器绘制视图之后,如果在此时改变DOM,有可能会导致浏览器再次回流和重绘。
除此之外useLayoutEffect的 callback 中代码执行会阻塞浏览器绘制
useDebugValue
可用于在 React 开发者工具中显示自定义 hook 的标签
useSyncExternalStore
是一个推荐用于读取和订阅外部数据源的 hook,其方式与选择性的 hydration 和时间切片等并发渲染功能兼容
const state = useSyncExternalStore(subscribe, getSnapshot[, getServerSnapshot])
subscribe: 订阅函数,用于注册一个回调函数,当存储值发生更改时被调用。此外,useSyncExternalStore会通过带有记忆性的getSnapshot来判别数据是否发生变化,如果发生变化,那么会强制更新数据。getSnapshot: 返回当前存储值的函数。必须返回缓存的值。如果getSnapshot连续多次调用,则必须返回相同的确切值,除非中间有存储值更新。getServerSnapshot:返回服务端(hydration模式下)渲染期间使用的存储值的函数
useTransition
返回一个状态值表示过渡任务的等待状态,以及一个启动该过渡任务的函数。
const [isPending, startTransition] = useTransition();
isPending:过渡状态的标志,为true时是等待状态startTransition:可以将里面的任务变成过渡任务
useDeferredValue
接受一个值,并返回该值的新副本,该副本将推迟到更紧急地更新之后。
如果当前渲染是一个紧急更新的结果,比如用户输入,React 将返回之前的值,然后在紧急渲染完成后渲染新的值。
也就是说useDeferredValue可以让状态滞后派生
const deferredValue = useDeferredValue(value);
value:可变的值,如useState创建的值deferredValue: 延时状态
useTransition和useDeferredValue对比
- 相同点:
useDeferredValue和useTransition一样,都是过渡更新任务 - 不同点:
useTransition给的是一个状态,而useDeferredValue给的是一个值
useInsertionEffect
与 useEffect一样,但它在所有 DOM 突变 之前同步触发。
在执行顺序上 useInsertionEffect > useLayoutEffect > useEffect
seInsertionEffect 应仅限于 css-in-js 库作者使用。优先考虑使用 useEffect 或 useLayoutEffect 来替代。
useId
useId : 是一个用于生成横跨服务端和客户端的稳定的唯一 ID 的同时避免hydration 不匹配的 hook。