1. useEffect Hook深入understanding
useEffect Hook用于processingcomponent 副作用, such asdata获取, subscribe or 手动DOMoperation.
1.1 useEffect 依赖项
useEffect接收两个parameter: 一个副作用function and 一个依赖项array.
// 依赖项 for 空array: 只 in component挂载时执行一次
useEffect(() => {
console.log('Component mounted');
return () => {
console.log('Component will unmount');
};
}, []);
// 依赖项 for 具体值: 当依赖项变化时执行
useEffect(() => {
console.log(`Count changed to: ${count}`);
}, [count]);
// 无依赖项: 每次渲染 after 都执行
useEffect(() => {
console.log('Component re-rendered');
});
提示
useEffect cleanfunction会 in component卸载 or 依赖项变化时执行, 用于清除副作用.
1.2 usinguseEffect获取data
function DataFetchingComponent() {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch('https://api.example.com/data');
const result = await response.json();
setData(result);
setLoading(false);
} catch (error) {
console.error('Error fetching data:', error);
setLoading(false);
}
};
fetchData();
}, []);
if (loading) {
return <div>Loading...</div>;
}
return (
<div>
{data.map(item => (
<div key={item.id}>{item.name}</div>
))}
</div>
);
}
2. useContext Hook
useContext Hook用于consumeContext, 避免了Context.Consumer 嵌套.
// creationContext
const ThemeContext = createContext('light');
// providingContext
function App() {
return (
<ThemeContext.Provider value="dark">
<ThemedComponent />
</ThemeContext.Provider>
);
}
// consumeContext
function ThemedComponent() {
const theme = useContext(ThemeContext);
return (
<div style={{
backgroundColor: theme === 'dark' ? '#333' : '#fff',
color: theme === 'dark' ? '#fff' : '#333',
padding: '20px'
}}>
Current theme: {theme}
</div>
);
}
3. useReducer Hook
useReducer Hook is useState 替代solutions, 适用于 complex statusmanagement.
// 定义reducerfunction
function counterReducer(state, action) {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 };
case 'DECREMENT':
return { count: state.count - 1 };
case 'RESET':
return { count: 0 };
case 'ADD':
return { count: state.count + action.payload };
default:
return state;
}
}
// usinguseReducer
function Counter() {
const [state, dispatch] = useReducer(counterReducer, { count: 0 });
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: 'INCREMENT' })}>Increment</button>
<button onClick={() => dispatch({ type: 'DECREMENT' })}>Decrement</button>
<button onClick={() => dispatch({ type: 'RESET' })}>Reset</button>
<button onClick={() => dispatch({ type: 'ADD', payload: 5 })}>Add 5</button>
</div>
);
}
4. useCallback and useMemo Hook
useCallback and useMemo用于optimizationcomponentperformance, 避免不必要 重 new 计算 and 渲染.
4.1 useCallback Hook
useCallback返回一个记忆化 callbackfunction, 只 has 当依赖项变化时才会重 new creation.
function ParentComponent() {
const [count, setCount] = useState(0);
const [message, setMessage] = useState('Hello');
// useCallback记忆化callbackfunction
const handleClick = useCallback(() => {
console.log('Button clicked');
}, []);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
<ChildComponent onClick={handleClick} />
</div>
);
}
// usingReact.memo避免不必要 重 new 渲染
const ChildComponent = React.memo(({ onClick }) => {
console.log('ChildComponent rendered');
return <button onClick={onClick}>Click me</button>;
});
4.2 useMemo Hook
useMemo返回一个记忆化 值, 只 has 当依赖项变化时才会重 new 计算.
function ExpensiveComponent() {
const [count, setCount] = useState(0);
const [number, setNumber] = useState(10);
// useMemo记忆化计算结果
const expensiveResult = useMemo(() => {
console.log('Calculating expensive result...');
let result = 0;
for (let i = 0; i < 100000000; i++) {
result += i;
}
return result;
}, [number]);
return (
<div>
<p>Count: {count}</p>
<p>Number: {number}</p>
<p>Expensive Result: {expensiveResult}</p>
<button onClick={() => setCount(count + 1)}>Increment Count</button>
<button onClick={() => setNumber(number + 1)}>Increment Number</button>
</div>
);
}
5. useRef Hook
useRef Hook用于creation一个可变 refobject, 用于访问DOM元素 or store任意值.
function RefComponent() {
const inputRef = useRef(null);
const countRef = useRef(0);
const handleFocus = () => {
inputRef.current.focus();
};
const handleClick = () => {
countRef.current += 1;
console.log('Clicked:', countRef.current);
};
return (
<div>
<input ref={inputRef} type="text" placeholder="Enter text" />
<button onClick={handleFocus}>Focus Input</button>
<button onClick={handleClick}>Click Me</button>
</div>
);
}
6. 自定义Hook
自定义Hook允许我们将component逻辑提取 to reusable functionin.
// 自定义Hook: useLocalStorage
function useLocalStorage(key, initialValue) {
// from localStorage获取初始值
const [value, setValue] = useState(() => {
try {
const item = localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
console.error(error);
return initialValue;
}
});
// updatelocalStorage并设置status
const setLocalStorageValue = (newValue) => {
try {
setValue(newValue);
localStorage.setItem(key, JSON.stringify(newValue));
} catch (error) {
console.error(error);
}
};
return [value, setLocalStorageValue];
}
// using自定义Hook
function LocalStorageComponent() {
const [name, setName] = useLocalStorage('name', '');
return (
<div>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Enter your name"
/>
<p>Hello, {name}!</p>
</div>
);
}
练习 1: usinguseEffect获取data
- creation一个component, usinguseEffect from API获取data
- implementation加载status and errorprocessing
- usinguseCallbackoptimizationeventprocessingfunction
练习 2: creation自定义Hook
- creation一个useDebounce自定义Hook, 用于防抖processing
- in 搜索componentinusing该Hook, implementation输入防抖