基础 Hooks
useState:状态管理
- 作用:在函数组件中声明和更新局部状态。
实战场景:表单输入、计数器、开关状态。
import React, { useState } from 'react'; function Counter() { const [count, setCount] = useState(0); return ( <div> <p>{count}</p> <button onClick={() => setCount(count + 1)}>+1</button> </div> ); }
useEffect:副作用处理
- 作用:处理副作用(如数据请求、DOM 操作、订阅)。
- 实战场景:API 请求、事件监听、定时器。
import React, { useState, useEffect } from 'react';
function DataFetcher() {
const [data, setData] = useState(null);
useEffect(() => {
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => setData(data));
return () => {
// 清理逻辑(如取消请求、移除监听)
};
}, []); // 空依赖数组表示只在挂载时执行
return <div>{data ? data.title : 'Loading...'}</div>;
}
useContext:共享全局数据
- 作用:跨组件树传递数据,避免逐层传递 props。
- 实战场景:主题切换、用户登录状态。
import React, { createContext, useContext } from 'react';
const ThemeContext = createContext('light');
function App() {
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
function Toolbar() {
const theme = useContext(ThemeContext);
return <div style={{ background: theme === 'dark' ? '#333' : '#fff' }}>Theme</div>;
}
进阶 Hooks
useReducer:复杂状态逻辑
- 作用:类似 Redux,通过 reducer 函数管理复杂状态。
实战场景:表单多字段管理、购物车状态。
import React, { useReducer } from 'react'; 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 ( <div> <p>{state.count}</p> <button onClick={() => dispatch({ type: 'increment' })}>+1</button> </div> ); }
useCallback:缓存函数
- 作用:缓存函数引用,避免子组件不必要的渲染。
- 实战场景:性能优化,防止函数重复创建。
import React, { useCallback, useState } from 'react';
function Parent() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
setCount(prev => prev + 1);
}, []); // 依赖数组为空表示函数不变化
return <Child onClick={handleClick} />;
}
const Child = React.memo(({ onClick }) => {
return <button onClick={onClick}>Click me</button>;
});
useMemo:缓存计算结果
- 作用:缓存复杂计算结果,避免重复计算。
- 实战场景:计算密集型操作、过滤列表。
import React, { useMemo, useState } from 'react';
function List({ items }) {
const [filter, setFilter] = useState('');
const filteredItems = useMemo(() => {
return items.filter(item => item.includes(filter));
}, [items, filter]); // 依赖变化时重新计算
return (
<div>
<input value={filter} onChange={(e) => setFilter(e.target.value)} />
<ul>{filteredItems.map(item => <li key={item}>{item}</li>}</ul>
</div>
);
}
useRef:引用 DOM 或保存可变值
- 作用:访问 DOM 元素或保存不触发渲染的变量。
实战场景:输入框聚焦、保存定时器 ID。
import React, { useRef, useEffect } from 'react'; function InputFocus() { const inputRef = useRef(null); useEffect(() => { inputRef.current.focus(); // 组件挂载后自动聚焦 }, []); return <input ref={inputRef} type="text" />; }
其他实用 Hooks
useLayoutEffect:同步副作用
- 作用:类似 useEffect,但会在 DOM 更新后同步执行。
实战场景:测量 DOM 元素尺寸、同步渲染前操作。
import React, { useLayoutEffect, useRef } from 'react'; function MeasureElement() { const ref = useRef(null); useLayoutEffect(() => { const { width } = ref.current.getBoundingClientRect(); console.log('Width:', width); }, []); return <div ref={ref}>Measure me</div>; }
useImperativeHandle:暴露子组件方法
- 作用:自定义通过 ref 暴露给父组件的方法。
实战场景:表单验证、控制子组件行为。
import React, { useRef, useImperativeHandle, forwardRef } from 'react'; const Child = forwardRef((props, ref) => { const inputRef = useRef(); useImperativeHandle(ref, () => ({ focus: () => inputRef.current.focus(), })); return <input ref={inputRef} />; }); function Parent() { const childRef = useRef(); return ( <div> <Child ref={childRef} /> <button onClick={() => childRef.current.focus()}>Focus Child</button> </div> ); }
useDebugValue:调试自定义 Hook
- 作用:在 React 开发者工具中显示自定义 Hook 的标签。
- 实战场景:调试复杂自定义 Hook。
function useCustomHook() {
const [value] = useState('Initial');
useDebugValue(value); // 在开发者工具中显示值
return value;
}
Hooks 组合实战
场景:全局状态管理(useContext + useReducer)
// 创建全局状态上下文
const AppContext = createContext();
function App() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<AppContext.Provider value={{ state, dispatch }}>
<ChildComponent />
</AppContext.Provider>
);
}
function ChildComponent() {
const { state, dispatch } = useContext(AppContext);
return <div>{state.count}</div>;
}
场景:防抖搜索(useState + useEffect + useCallback)
function Search() {
const [query, setQuery] = useState('');
const [results, setResults] = useState([]);
const debouncedSearch = useCallback(
_.debounce((searchText) => {
fetchResults(searchText).then(setResults);
}, 500),
[]
);
useEffect(() => {
if (query) debouncedSearch(query);
}, [query]);
return (
<div>
<input value={query} onChange={(e) => setQuery(e.target.value)} />
<ul>{results.map(result => <li key={result.id}>{result.name}</li>}</ul>
</div>
);
}
Hooks 使用规则
- 只在顶层调用:不要在循环、条件或嵌套函数中使用 Hooks。
- 仅在函数组件或自定义 Hook 中使用:不可在普通 JavaScript 函数中使用。
本文由mdnice多平台发布
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。