react-hook-form 结合 zustand 的写法时, 在组件 useEffect 内部调用 useStore的方法,在组件内 获取 useStore 的值,但是值为空, 怎么解决? 代码应该怎么修改更加具有性能优化
当在 react-hook-form 结合 zustand 时,如果在 useEffect 内部调用 useStore 的方法并发现值为空,这通常是因为 useEffect 的执行时机问题,或者是 zustand 状态在 useEffect 调用时尚未准备好。为了优化性能,可以采取以下几种方法:
优化方案
1. 使用 zustand 的 subscribe 监听状态变化
通过 zustand 的 subscribe 机制监听状态的变化,并在状态更新时设置 react-hook-form 的值。这种方法确保在 zustand 的状态准备好时,及时更新表单值。
import React, { useEffect } from 'react';
import { useForm } from 'react-hook-form';
import { useStore } from './store'; // 从 zustand 获取 store
function MyForm() {
const { register, handleSubmit, setValue } = useForm();
const formData = useStore((state) => state.formData); // 获取状态
const subscribe = useStore((state) => state.subscribe);
useEffect(() => {
if (formData) {
setValue('firstName', formData.firstName);
setValue('lastName', formData.lastName);
}
// 订阅状态变化
const unsubscribe = subscribe((newState) => {
if (newState.formData) {
setValue('firstName', newState.formData.firstName);
setValue('lastName', newState.formData.lastName);
}
});
return () => unsubscribe(); // 清理订阅
}, [formData, setValue, subscribe]);
const onSubmit = (data) => {
console.log(data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register('firstName')} placeholder="First Name" />
<input {...register('lastName')} placeholder="Last Name" />
<button type="submit">Submit</button>
</form>
);
}
export default MyForm;
2. 使用 defaultValues 初始化表单
在表单初始化时通过 useForm 的 defaultValues 直接设置表单默认值。如果 zustand 的状态在组件渲染时就已经准备好,这种方法最为简洁和高效。
import React from 'react';
import { useForm } from 'react-hook-form';
import { useStore } from './store';
function MyForm() {
const formData = useStore((state) => state.formData);
const { register, handleSubmit } = useForm({
defaultValues: formData, // 使用 Zustand 的状态初始化表单
});
const onSubmit = (data) => {
console.log(data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register('firstName')} placeholder="First Name" />
<input {...register('lastName')} placeholder="Last Name" />
<button type="submit">Submit</button>
</form>
);
}
export default MyForm;
3. 避免不必要的重新渲染
在 zustand 状态变化时,确保只更新必要的组件,以避免不必要的重新渲染。通过将 zustand 的选择器函数细化,只订阅与组件相关的状态部分。
import React from 'react';
import { useForm } from 'react-hook-form';
import { useStore } from './store';
function MyForm() {
const formData = useStore((state) => state.formData);
const { register, handleSubmit } = useForm({
defaultValues: formData, // 直接使用状态初始化表单
});
const onSubmit = (data) => {
console.log(data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register('firstName')} placeholder="First Name" />
<input {...register('lastName')} placeholder="Last Name" />
<button type="submit">Submit</button>
</form>
);
}
export default MyForm;
总结
为了解决在 useEffect 中调用 useStore 时状态为空的问题,建议使用 zustand 的 subscribe 方法来监听状态变化,或者直接使用 defaultValues 初始化表单,确保状态在渲染前已准备好。通过优化状态订阅和减少不必要的重新渲染,可以进一步提升性能。