useState
場景:組件中管理局部狀態,如表單值、開關、計數器等。
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>Click {count}</button>;
useEffect
場景:
-
組件掛載時執行副作用(如請求數據、事件綁定)
-
依賴變化時觸發邏輯
-
卸載清理操作
useEffect(() => {const id = setInterval(() => console.log('tick'), 1000);return () => clearInterval(id); // 清理
}, []);
useContext
場景:狀態邏輯復雜或狀態之間有關聯的情況。常用于表單或狀態機。
多個組件傳值,層級復雜的組件之間數據傳遞,避免因為props造成難以維護的痛點
創建 context
const ThemeContext = React.createContext("light");
使用 Provider 包裹組件樹
<ThemeContext.Provider value="dark"><App />
</ThemeContext.Provider>
消費 context
const theme = useContext(ThemeContext);
return <div className={`theme-${theme}`}>當前主題:{theme}</div>;
useReducer
適用于狀態較復雜或狀態之間關聯性強的場景
基本語法
const [state, dispatch] = useReducer(reducer, initialState);
示例一:計數器
const reducer = (state, action) => {switch (action.type) {case 'increment': return state + 1;case 'decrement': return state - 1;default: return state;}
};
const [count, dispatch] = useReducer(reducer, 0);
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
useReducer + useContext 配合使用(全局狀態管理)
const AppContext = createContext(null);const initialState = { user: null };
function reducer(state, action) {switch (action.type) {case 'login': return { ...state, user: action.payload };case 'logout': return { ...state, user: null };default: return state;}
}function AppProvider({ children }) {const [state, dispatch] = useReducer(reducer, initialState);return (<AppContext.Provider value={{ state, dispatch }}>{children}</AppContext.Provider>);
}function useApp() {return useContext(AppContext);
}
useCallback
場景:
-
父組件傳遞函數給子組件
-
避免組件重復渲染
const handleClick = useCallback(() => doSomething(id), [id]);
useMemo
場景:
-
緩存計算結果
-
避免重復渲染時昂貴計算
const expensiveValue = useMemo(() => computeExpensiveValue(data), [data]);
useRef
場景:
-
訪問 DOM 元素
-
保存可變值不觸發重渲染(如定時器ID
const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => inputRef.current?.focus(), []);
useImperativeHandle
場景:暴露子組件的內部方法給父組件(配合 forwardRef 使用)
useImperativeHandle(ref, () => ({focus: () => inputRef.current?.focus()
}));
useLayoutEffect
場景:
- 在 DOM 渲染之前同步執行副作用(如測量 DOM)
useLayoutEffect(() => {const height = ref.current.offsetHeight;// 設置樣式
}, []);
與 useEffect 類似,但在 DOM 渲染前 執行,可能阻塞繪制。
useDebugValue
useDebugValue(state ? "Online" : "Offline");
react18 相關hooks
useTransition
場景:將更新標記為“過渡”,提升響應性(如搜索輸入)
const [isPending, startTransition] = useTransition();
startTransition(() => setSearchQuery(value));
useDeferredValue
場景:延遲某個值的更新,防止因頻繁輸入導致 UI 卡頓
const deferredQuery = useDeferredValue(query);
useId
場景:在客戶端和服務端生成一致的唯一 ID(用于可訪問性)
const id = useId();
<label htmlFor={id}>Name</label>
<input id={id} />
useSyncExternalStore
場景:訂閱外部 store(如 Redux、MobX、Zustand)
const state = useSyncExternalStore(subscribe, getSnapshot);
useInsertionEffect
場景:比 useLayoutEffect 更早執行,用于樣式注入等場景(如 CSS-in-JS)
useInsertionEffect(() => {// 注入樣式
}, []);