react hooks

useState#

setState 可以设置具体的值,也可以通过函数,利用先前的值计算得出

Copy
setState(prevState => { // 也可以使用 Object.assign return {...prevState, ...updatedValues}; });

useEffect#

若在 useEffect 中使用 useState, 那么 useEffect 的第二个条件参数(依赖项)不能设置对象,否则进入死循环。因为若设置对象,则每次都会进入到 useEffect 中,由于在 useEffect 中调用 setState,则会导致页面重新渲染,而页面重新渲染,就又会进入到 useEffect中......

useReducer#

const [state, dispatch] = useReducer(reducer, initialArg, init);

它是 useState 的替换方案。

Copy
const initialState = {count: 0}; function reducer(state, action) { switch (action.type) { case 'increment': return {count: state.count + 1}; case 'decrement': return {count: state.count - 1}; default: throw new Error(); } } function Counter() { const [state, dispatch] = useReducer(reducer, initialState); return ( <> Count: {state.count} <button onClick={() => dispatch({type: 'decrement'})}>-</button> <button onClick={() => dispatch({type: 'increment'})}>+</button> </> ); }

useDispatch & useSelector: 可以完全代替 redux#

Copy
import { useDispatch, useSelector } from 'dva'; const dispatch = useDispatch(); // 从model仓库中取数据 const { projectList } = useSelector((state) => state.appInfo); const appInfo = useSelector((state) => state.appInfo);

useCallback / useMemo#

用于缓存数据,优化性能的钩子函数,

useCallback(fn, deps) 相当于 useMemo(() => fn, deps)

共同作用:

当依赖数据发生变化时,才会调用传进去的回调函数去重新计算结果,起到一个缓存的作用

不同作用:

  • useMemo 缓存的结果是回调函数中return回来的值,主要用于缓存计算结果的值,应用场景如需要计算的状态
  • useCallback 缓存的结果是函数,主要用于缓存函数。但它需要和React.memo 配套使用,缺少任意一个都可能导致性能不升反降

useCallback#

用于某函数无需反复渲染。

Copy
map.addEventListener('rightclick', onRightClick); const onRightClick = useCallback(() => { const markerMenu = new BMap.ContextMenu(); markerMenu.addItem( new BMap.MenuItem('设为终点', (e) => { const geoc = new BMap.Geocoder(); let address = ''; }), ); map.addContextMenu(markerMenu); }, [map]);

useMemo#

相当于class组件的 pureComponent , 可以缓存整个函数组件

useRef#

const refContainer = useRef(initialValue);

useRef 返回一个可变的 ref 对象,其 .current 属性被初始化为传入的参数(initialValue)。返回的 ref 对象在组件的整个生命周期内保持不变

三种用法:

(一):命令式的访问子组件

Copy
function TextInputWithFocusButton() { const inputEl = useRef(null); const onButtonClick = () => { // `current` 指向已挂载到 DOM 上的文本输入元素 inputEl.current.focus(); }; return ( <> <input ref={inputEl} type="text" /> <button onClick={onButtonClick}>Focus the input</button> </> ); }

(二):非常方便的保存任何值

Copy
const draggingRef = useRef(null); const handleDragStart = e => { e.stopPropagation?.(); draggingRef.current = e.currentTarget; };
Copy
const formRef = useRef(null); useEffect(() => { formRef.current = form; }, [form]); useEffect(() => { dispatch({ type: `${currentModel}/overrideStateProps`, payload: { accessoryInfoForm: formRef, }, }); }, [dispatch, formRef, currentModel]);

(三):访问DOM的主要方式

将 ref 对象以 <div ref={myRef} /> 形式传入组件,则无论该节点如何改变,React 都会将 ref 对象的 .current 属性设置为相应的 DOM 节点。

当 ref 对象内容发生变化时,useRef不会通知你。变更 .current 属性不会引发组件重新渲染。如果想要在 React 绑定或解绑 DOM 节点的 ref 时运行某些代码,则需要使用回调 ref 来实现。

useImperativeHandle#

useImperativeHandle 可以让我们在使用 ref 时自定义暴露给父组件的实例值,即有选择性的暴露出去,而不是全部暴露。

Copy
function FancyInput(props, ref) { const inputRef = useRef(); useImperativeHandle(ref, () => ({ focus: () => { inputRef.current.focus(); } })); return <input ref={inputRef} ... />; } FancyInput = forwardRef(FancyInput);

useLayoutEffect#

useEffect 用法一样。但 useEffect 有延迟,而 useLayoutEffect 没有延迟,它在读取DOM布局后就同步触发重渲染。即:在浏览器执行绘制之前,useLayoutEffect 内部的更新计划将被同步刷新。

一开始先用 useEffect,只有当它出问题的时候再尝试使用 useLayoutEffect

若要从服务端渲染的 HTML 中排除依赖布局 effect 的组件,可以通过使用 showChild && <Child /> 进行条件渲染,并使用 useEffect(() => { setShowChild(true); }, []) 延迟展示组件。这样,在客户端渲染完成之前,UI 就不会像之前那样显示错乱了。

posted @   小蜗蜗蜗牛^o^  阅读(50)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示
CONTENTS