简述React自定义Hooks
React 的自定义 Hooks 是复用逻辑的一种方式,它们使得我们可以在函数组件中提取和共享状态逻辑,避免重复代码,提高可维护性。以下是如何创建和封装自定义 Hooks 的详细步骤。
1. 创建自定义 Hooks 的基本结构
自定义 Hooks 是一个以 use
开头的函数,遵循 React 的 Hook 规则。基本结构如下:
import { useState, useEffect } from 'react';
function useCustomHook() {
// 定义状态
const [state, setState] = useState(initialValue);
// 副作用逻辑
useEffect(() => {
// 执行副作用
return () => {
// 清理副作用
};
}, [dependencies]);
return [state, setState];
}
2. 参数化自定义 Hooks
自定义 Hooks 可以接受参数,从而使其更具通用性。例如,一个处理输入框逻辑的自定义 Hook:
import { useState } from 'react';
function useInput(initialValue) {
const [value, setValue] = useState(initialValue);
const handleChange = (event) => {
setValue(event.target.value);
};
return [value, handleChange];
}
3. 使用自定义 Hooks
在组件中使用自定义 Hooks 与使用 React 内置 Hooks 没有本质区别。调用自定义 Hook 并获取返回值即可:
function MyComponent() {
const [inputValue, handleInputChange] = useInput('');
return (
<input
type="text"
value={inputValue}
onChange={handleInputChange}
/>
);
}
4. 结合其他 Hooks
自定义 Hooks 可以组合多个内置 Hooks 或其他自定义 Hooks。以下是一个结合 useState
和 useEffect
的示例:
import { useState, useEffect } from 'react';
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch(url)
.then((response) => response.json())
.then((data) => {
setData(data);
setLoading(false);
});
}, [url]);
return { data, loading };
}
5. 封装复杂逻辑
对于复杂的逻辑,比如需要处理多个状态或副作用的情况,自定义 Hooks 可以极大地简化组件代码。以下是一个处理窗口尺寸变化的自定义 Hook:
import { useState, useEffect } from 'react';
function useWindowSize() {
const [windowSize, setWindowSize] = useState({
width: window.innerWidth,
height: window.innerHeight,
});
useEffect(() => {
const handleResize = () => {
setWindowSize({
width: window.innerWidth,
height: window.innerHeight,
});
};
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);
return windowSize;
}
6. 自定义 Hooks 的优化
在创建自定义 Hooks 时,要注意避免不必要的重新渲染。可以通过 useMemo
和 useCallback
等 Hooks 来优化性能。例如,在处理复杂计算或需要保持函数引用稳定时,可以这样使用:
import { useMemo, useCallback } from 'react';
function useExpensiveCalculation(input) {
const result = useMemo(() => {
return computeExpensiveValue(input);
}, [input]);
const handleSomething = useCallback(() => {
// 一些依赖 result 的操作
}, [result]);
return [result, handleSomething];
}
7. 常见 Hooks 第三方库
以上是 React Hooks 工具库,提供了上百个高质量的自定义 Hooks,涵盖了各种常见的需求。 除了这些,像React Query、Recoil、Zustand等都是通过hooks提供api。