React 函数组件 最初没有类组件那样的生命周期方法,但是自从 React 16.8 引入了 Hooks,函数组件也可以通过使用各种 Hook 来实现类似的生命周期行为。以下是一些常用的 Hook 及其用途:
useState
用于在函数组件中添加状态。
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
useEffect
用于在函数组件中执行副作用操作,比如数据获取、订阅或手动更改DOM。它可以看作是 componentDidMount、componentDidUpdate 和 componentWillUnmount 的组合。
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
// 类似于 componentDidMount 和 componentDidUpdate:
useEffect(() => {
// 使用浏览器API更新页面标题
document.title = `You clicked ${count} times`;
// 返回一个清理函数,类似于 componentWillUnmount
return () => {
console.log('Cleanup');
};
}, [count]); // 仅在 count 更改时重新运行
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
useContext
用于在函数组件中使用上下文,相当于类组件中的 contextType 或 Context.Consumer。
import React, { useContext } from 'react';
const ThemeContext = React.createContext('light');
function ThemedButton() {
const theme = useContext(ThemeContext);
return <button style={{ background: theme === 'dark' ? '#333' : '#FFF' }}>Themed Button</button>;
}
useReducer
用于在函数组件中管理复杂状态逻辑,相当于 Redux 的 reducer。
import React, { useReducer } from 'react';
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, { count: 0 });
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
<button onClick={() => dispatch({ type: 'decrement' })}>-</button>
</div>
);
}
useRef
用于在函数组件中引用DOM元素或存储一个可变值,这个值在整个组件生命周期内保持不变。
import React, { useRef, useEffect } from 'react';
function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
// `current` 指向已挂载到 DOM 上的文本输入元素
inputEl.current.focus();
};
return (
<div>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</div>
);
}
useMemo 和 useCallback
用于性能优化,通过缓存计算结果或函数避免不必要的重新计算或重新创建。
-
useMemo 用于缓存计算结果。
import React, { useMemo } from 'react'; function ExpensiveCalculationComponent({ a, b }) { const result = useMemo(() => { // 一些计算量大的操作 return a + b; }, [a, b]); return <div>{result}</div>; } -
useCallback 用于缓存函数。
import React, { useCallback } from 'react'; function ParentComponent() { const handleClick = useCallback(() => { // 一些处理操作 }, []); return <ChildComponent onClick={handleClick} />; }
通过这些 Hooks,函数组件能够实现与类组件相同的功能,并且通常更简洁、易于理解和测试。