React 钩子(Hooks)是 React 16.8 引入的新特性,允许你在函数组件中使用状态和其他 React 特性。以下是一些常用的 React 钩子及其详细解释:
1. useState
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>
);
}
useState(initialValue)
:接受一个初始状态值,并返回一个状态变量和更新状态的函数。- 状态变量:保存当前状态值。
- 更新函数:用于更新状态。
2. useEffect
useEffect
钩子允许你在函数组件中执行副作用(例如,数据获取、订阅或手动操作 DOM)。
import React, { useEffect, useState } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
useEffect(callback, dependencies)
:接受一个副作用函数和一个依赖项数组。- 副作用函数:在组件渲染后执行。
- 依赖项数组:控制副作用的执行时机,只有依赖项变化时才会重新执行副作用。
3. useContext
useContext
钩子用于在函数组件中使用上下文。
import React, { useContext } from 'react';
const ThemeContext = React.createContext('light');
function ThemedButton() {
const theme = useContext(ThemeContext);
return (
<button className={theme}>
I am styled by theme context!
</button>
);
}
useContext(Context)
:接受一个上下文对象,并返回当前上下文值。
4. useReducer
useReducer
钩子是 useState
的替代方案,用于更复杂的状态逻辑。
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>
Count: {state.count}
<button onClick={() => dispatch({ type: 'increment' })}>
+
</button>
<button onClick={() => dispatch({ type: 'decrement' })}>
-
</button>
</div>
);
}
useReducer(reducer, initialState)
:接受一个 reducer 函数和初始状态,并返回当前状态和 dispatch 函数。- reducer:定义了如何根据 action 更新状态。
- dispatch:发送 action 来触发状态更新。
5. useMemo
useMemo
钩子用于记忆化(缓存)计算结果,以优化性能。
import React, { useMemo, useState } from 'react';
function ExpensiveComponent({ input }) {
const computeExpensiveValue = (input) => {
// 假设这是一个昂贵的计算
return input * 2;
};
const memoizedValue = useMemo(() => computeExpensiveValue(input), [input]);
return <div>{memoizedValue}</div>;
}
useMemo(callback, dependencies)
:只有当依赖项变化时才会重新计算 memoized 值。
6. useCallback
useCallback
钩子用于记忆化(缓存)回调函数,以避免不必要的重新渲染。
import React, { useCallback, useState } from 'react';
function MyComponent() {
const [count, setCount] = useState(0);
const increment = useCallback(() => {
setCount(count + 1);
}, [count]);
return (
<div>
<button onClick={increment}>Increment</button>
<p>{count}</p>
</div>
);
}
useCallback(callback, dependencies)
:返回记忆化的回调函数,只有当依赖项变化时才会更新。
7. useRef
useRef
钩子用于创建一个可变的 ref 对象,该对象在组件的整个生命周期中保持不变。
import React, { useRef } from 'react';
function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
inputEl.current.focus();
};
return (
<div>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</div>
);
}
useRef(initialValue)
:返回一个可变的 ref 对象,该对象的.current
属性被初始化为传入的参数。
这些钩子可以单独使用,也可以组合使用,以满足不同的需求。通过合理使用这些钩子,可以使你的函数组件更加简洁和高效。