js实现hooks
实现自定义 Hooks 的基本概念
自定义 Hooks 是封装可复用逻辑的函数,需遵循命名以 use 开头的约定。通过组合内置 Hooks(如 useState、useEffect),可提取组件中的状态或副作用逻辑。
创建状态管理 Hook
以下示例实现一个计数器 Hook,供多个组件复用:
function useCounter(initialValue = 0) {
const [count, setCount] = useState(initialValue);
const increment = () => setCount(count + 1);
const decrement = () => setCount(count - 1);
return { count, increment, decrement };
}
调用方式:
function Component() {
const { count, increment } = useCounter(0);
return <button onClick={increment}>Count: {count}</button>;
}
封装副作用逻辑
将数据获取逻辑抽象为 Hook:
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch(url)
.then(res => res.json())
.then(data => {
setData(data);
setLoading(false);
});
}, [url]);
return { data, loading };
}
使用示例:
function UserProfile({ userId }) {
const { data: user, loading } = useFetch(`/api/users/${userId}`);
if (loading) return <div>Loading...</div>;
return <div>{user.name}</div>;
}
实现生命周期模拟
通过 useEffect 模拟类组件的生命周期:
function useLifecycle({ onMount, onUnmount }) {
useEffect(() => {
onMount?.();
return () => onUnmount?.();
}, []);
}
应用场景:
function App() {
useLifecycle({
onMount: () => console.log('Component mounted'),
onUnmount: () => console.log('Component unmounted')
});
return <div>Check console logs</div>;
}
注意事项
- 规则遵循:只在函数组件或其它 Hooks 中调用 Hooks,避免条件语句中使用。
- 依赖项处理:
useEffect的依赖数组需明确声明所有外部依赖。 - 性能优化:使用
useMemo和useCallback避免不必要的计算或渲染。
复杂案例:表单管理 Hook
整合表单状态与验证逻辑:
function useForm(initialState, validate) {
const [values, setValues] = useState(initialState);
const [errors, setErrors] = useState({});
const handleChange = (e) => {
const { name, value } = e.target;
setValues(prev => ({ ...prev, [name]: value }));
};
const handleSubmit = (callback) => (e) => {
e.preventDefault();
const validationErrors = validate?.(values) || {};
if (Object.keys(validationErrors).length === 0) {
callback(values);
} else {
setErrors(validationErrors);
}
};
return { values, errors, handleChange, handleSubmit };
}
调用示例:

function LoginForm() {
const { values, errors, handleChange, handleSubmit } = useForm(
{ email: '', password: '' },
(values) => {
const errors = {};
if (!values.email) errors.email = 'Email required';
if (!values.password) errors.password = 'Password required';
return errors;
}
);
const onSubmit = (data) => console.log('Submit:', data);
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input name="email" value={values.email} onChange={handleChange} />
{errors.email && <span>{errors.email}</span>}
{/* 其他字段... */}
</form>
);
}






