React 中级教程
1. useState 与 setState 深入理解
import React, { useState } from 'react';
const Counter = () => {
const [count, setCount] = useState(0);
const increment = () => {
setCount(count + 1); // setState 会异步更新
};
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
</div>
);
};
export default Counter;
概述: useState
是 React 中的一个核心 Hook,用于声明组件状态。使用 useState
时,状态的更新通常是异步的,可能在事件处理和渲染周期中产生一些延迟。在此示例中,count
作为一个状态变量,setCount
用来更新它。这个机制使得 React 能够更高效地管理和更新 UI。
2. useEffect 副作用和清理
import React, { useState, useEffect } from 'react';
const Timer = () => {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setSeconds(prev => prev + 1);
}, 1000);
return () => clearInterval(interval); // 清理定时器
}, []); // 空数组表示只在组件挂载时执行一次
return <div>Time: {seconds}s</div>;
};
export default Timer;
概述: useEffect
用于处理副作用,例如定时器、网络请求和 DOM 操作。通过传递空数组作为依赖项,确保副作用只在组件挂载时执行一次。在清理阶段,useEffect
返回一个清理函数来避免内存泄漏和无效的副作用,如这里的定时器。
3. 自定义 Hook:使用 LocalStorage
import { useState, useEffect } from 'react';
function useLocalStorage(key, initialValue) {
const [value, setValue] = useState(() => {
const storedValue = window.localStorage.getItem(key);
return storedValue ? JSON.parse(storedValue) : initialValue;
});
useEffect(() => {
window.localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);
return [value, setValue];
}
const App = () => {
const [name, setName] = useLocalStorage('name', 'Guest');
return (
<div>
<input value={name} onChange={(e) => setName(e.target.value)} />
<p>Welcome, {name}!</p>
</div>
);
};
export default App;
概述: 自定义 Hook 允许你将逻辑复用到多个组件中。此示例展示了如何创建一个处理 LocalStorage 的自定义 Hook,确保状态在页面刷新时保持。它利用 useState
初始化值,并通过 useEffect
更新 localStorage
。
4. 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:
return state;
}
}
const Counter = () => {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
<button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button>
</div>
);
};
export default Counter;