常用 Hooks 详解
useState - 状态管理
javascript
const [count, setCount] = useState(0);
// 函数式更新
setCount((prevCount) => prevCount + 1);useReducer - 复杂状态管理
复杂状态管理,类似 Redux:
javascript
const initialState = { count: 0 };
function reducer(state, action) {
switch (action.type) {
case "ADD":
return { count: state.count + 1 };
case "MINUS":
return { count: state.count - 1 };
default:
return state;
}
}
const [state, dispatch] = useReducer(reducer, initialState);
dispatch({ type: "ADD" });useEffect - 副作用处理
处理副作用,替代类组件的生命周期:
javascript
useEffect(() => {
// 相当于 componentDidMount
const timer = setInterval(() => {
setCount((count) => count + 1);
}, 1000);
// 返回清理函数,相当于 componentWillUnmount
return () => {
clearInterval(timer);
};
}, []); // 空依赖数组 = 只执行一次
// 带依赖的 effect
useEffect(() => {
// 当 count 变化时执行
console.log("Count changed:", count);
}, [count]);useContext - 跨组件共享数据
javascript
const MyContext = createContext("defaultValue");
// 提供数据
<MyContext.Provider value="hello">
<Child />
</MyContext.Provider>;
// 消费数据
function Child() {
const value = useContext(MyContext);
return <div>{value}</div>;
}useMemo - 缓存计算结果
javascript
const displayData = useMemo(() => ({ count }), [count]);useCallback - 缓存回调函数
javascript
const incrementCount = useCallback(() => {
setCount((count) => count + 1);
}, [count]);useRef - 引用 DOM
在函数组件中创建 ref:
javascript
const inputRef = useRef(null); // {current: null}
function focusInput() {
inputRef.current.focus();
}
<input ref={inputRef} />;useImperativeHandle - 自定义 ref 暴露
自定义 ref 暴露给父组件的实例值:
javascript
function FancyInput(props, ref) {
const inputRef = useRef();
useImperativeHandle(ref, () => ({
focus() {
inputRef.current.focus();
},
}));
return <input ref={inputRef} />;
}
const ForwardFancyInput = forwardRef(FancyInput);useLayoutEffect - 同步副作用
同步执行副作用,在 DOM 变更后同步调用(阻塞浏览器绘制):
javascript
useLayoutEffect(() => {
// 在浏览器绘制之前执行
ref.current.style.transform = `translate(500px)`;
}, []);Ref 引用
createRef(类组件)
用于访问 DOM 元素或类组件实例:
javascript
class RefComponent extends React.Component {
inputRef = React.createRef(); // {current: null}
handleButtonClick = () => {
this.inputRef.current.focus(); // 访问真实 DOM
};
render() {
return (
<div>
<input ref={this.inputRef} type="text" />
<button onClick={this.handleButtonClick}>获得焦点</button>
</div>
);
}
}访问类组件实例
javascript
class ParentComponent extends React.Component {
childRef = React.createRef();
handleClick = () => {
this.childRef.current.alertMessage(); // 调用子组件方法
};
render() {
return (
<div>
<ChildComponent ref={this.childRef} />
</div>
);
}
}forwardRef(转发 ref)
函数组件默认不能接收 ref,需要使用 forwardRef:
javascript
function ChildComponent(props, forwardRef) {
return <input ref={forwardRef} />;
}
const ForwardChildComponent = React.forwardRef(ChildComponent);