普通视图

发现新文章,点击刷新页面。
今天 — 2025年7月3日首页

react 基础API

作者 Rubin93
2025年7月3日 15:03

1. useEffect

  1. 浏览器重新绘制之后触发
  2. 参数(setup,dependencies?)
  3. 异步执行
  4. 挂载组件时执行setup,依赖更新时先执行cleanup,再执行setup

2. useLayoutEffect

  1. 浏览器重新绘制之前触发
  2. 参数(setup,dependencies?)
  3. 同步执行,会阻塞DOM渲染
  4. 挂载组件时执行setup,依赖更新时先执行cleanup,再执行setup

3. useReducer

const [state, dispatch] = useReducer(reducerFn, initiaValue, inituaValueFn?)

reducerFn:处理函数,参数:state, action,返回值:新的state
initiaValue:state默认值
inituaValueFn:默认值函数,用于初始化state,优先执行,非必填


const reducerfn = (state, action) => {
if (action==='inc') {
return state++
}
if (action==='dec') {
return state--
}
}
const [state, dispatch] = useReducer(reducerfn, -1, ()=> {
// 高于默认值的优先级
return 0
})

<Button onClick={() => dispatch('inc')}>增加</Button>
<Button onClick={() => dispatch('dec')}>减少</Button>

4. useSyncExternalStore

useSyncExternalStore 用于从外部存储(例如状态管理库、浏览器 API等)获取状态并在组件中同步显示。跟踪外部状态。

useSyncExternalStore 使用场景:

  1. 订阅外部 store 例如(redux,mobx,Zustand,jotai)
  2. 订阅浏览器AP| 例如(online,storage,location, history hash)等

抽离逻辑,编写自定义hooks

const res = useSyncExternalStore(subscribe, getSnapshot, getSeeverSnapShot?)
sybscribe:订阅数据源的变化,接受一个回调函数在数据源更新时调用此函数
getSnapShot:获取当前数据源的快照(当前信息)
getSeeverSnapShot:服务端使用

// hooks/useStorage.tsx
import { useSyncExternalStore } from 'react'
export const useStorage = (key: string, initiaValue: number) => {
const subscribe = (callback: () => void) => {
window.addEventListener('storage', callback)
return () => {
window.removeEventListener('storage', callback)
}
}
const getSnapShot = () => {
return localStorage.getItem(key) ? JSON.parse(localStorage.getItem(key)!) : initiaValue
}
const data = useSyncExternalStore(subscribe, getSnapShot)
const setData = (value: any) => {
localStorage.setItem(key, JSON.stringify(value))
// 手动触发eventStorage事件,通知订阅
window.dispatchEvent(new Event('storage'))
}
return [data, setData]
}

// views/page.tsx
import { useStorage } from "./hooks/useStorage";
function App() {
  const [token, setToken] = useStorage('token', 0)
  return (
    <>
      <h1>hooks useStorage</h1>
      <div>
        <p> token is {token} </p>
        <button onClick={() => setToken(token + 1)}> token ++ </button>
        <button onClick={() => setToken(token - 1)}> token -- </button>
      </div>
    </>
  )
}
export default App

5. useTransition

useTransition 用于优化用户界面响应性的 Hook,它允许你在不阻塞用户交互的前提下,优雅地处理状态更新带来的加载状态(如“挂起”或“过渡”)

useTransition 作用:

  • 状态更新通常是同步的,调用 setState 会立即重新渲染组件树,可能会导致页面卡顿,特别是在处理复杂计算或大量数据更新时。useTransition 将某些状态更新标记为“非紧急”(过渡态),从而优先处理更紧急的 UI 更新(比如输入框的响应) 。

useTransition 使用场景:

  1. 数据加载时的“pending”状态展示
  2. 页面切换时的平滑过渡
  3. 大型表单提交等场景

6. useDeferredValue

useDeferredValue 用于优化用户界面响应性的 Hook,它允许你在不阻塞渲染的前提下,延迟更新某些非紧急的状态值,从而保持 UI 的流畅性。

useDeferredValue 作用:

  • 延迟使用新的值进行渲染,优先显示旧值,直到浏览器空闲时再更新为新值。

useDeferredValue 使用场景:

  1. 搜索输入框的自动补全
  2. 列表滚动时的平滑更新
  3. 大量数据展示时的渐进式渲染

7. useDeferred 对比 useTransition

特性 useDeferredValue useTransition
控制对象 值(value) 状态更新(state update)
是否需要包装副作用
是否有 isPending 状态
适用场景 延迟更新某个值(如列表、文本) 控制状态更新优先级,显示 loading 状态

8. useImperativeHandle & forwardRef

用于自定义暴露子组件方法或属性给父组件调用的 Hook,它通常与 forwardRef 一起使用。

import { useImperativeHandle, forwardRef, useRef } from "react";

// 子组件,必须配合 forwardRef
const Child_ = forwardRef((props, ref)=>{
  const Child_reff = useRef(null)
  const focusInput = () => { 
    Child_reff.current!.focus()
  }
  const selectInput = () => {
    Child_reff.current!.select()
  }
  const BlurInput = () => {
    Child_reff.current!.blur()
  }
  // 暴露方法给父组件
  useImperativeHandle(ref,() => ({
    focus: focusInput,
    select: selectInput,
    blur: BlurInput,
  }))
  return <input ref={Child_reff} type="text" />
})

// 父组件
function Parent_() {
  const inputRef = useRef(null);
  const handleFocus = () => {
    inputRef.current!.focus(); // 调用子组件方法
  };
  const handleSelect = () => {
    inputRef.current!.select(); // 调用子组件方法
  };
  const handleBlur = () => {
    inputRef.current!.blur(); // 调用子组件方法
  };
  return (
    <>
        <div>
          <h1>hooks useImperativeHandle forwardRef</h1>
          <p> useImperativeHandle  </p>
          <br />
          <Child_ ref={inputRef} />
          <button onClick={handleFocus}>输入框聚焦</button>
          <button onClick={handleSelect}>选中输入框文本</button>
          <button onClick={handleBlur}>输入框失焦</button>
      </div>
    </>
  )
}

export default Parent_
❌
❌