- 作者:老汪软件技巧
- 发表时间:2024-08-19 15:03
- 浏览量:
为了确保在组件的第一次 render 时 useForm 的 defaultValues 能够拿到来自 store 的值,可以提前将 store 中的数据加载完毕后再初始化表单。以下是几种方法:
方法一:在父组件中提前加载数据
在组件挂载前通过父组件或其他逻辑提前从 store 中获取数据,并将其作为 props 传递给表单组件,这样可以确保表单组件在第一次 render 时已经有了所需的 defaultValues。
import React, { useEffect } from 'react';
import { useForm } from 'react-hook-form';
import { useStore } from './store';
function MyForm({ initialData }) {
const { register } = useForm({
defaultValues: initialData, // 将从父组件传递的初始数据作为 defaultValues
});
return (
<form>
<input {...register("field1")} />
<input {...register("field2")} />
{/* 其他表单字段 */}
form>
);
}
function ParentComponent() {
const data = useStore(state => state.data);
if (!data) return <div>Loading...div>; // 确保数据在渲染表单前已经加载完毕
return <MyForm initialData={data} />;
}
方法二:在组件内部提前加载数据
你可以在组件内部使用 useEffect 钩子提前加载数据,并在数据加载完成后再初始化表单。通过将表单的渲染延迟到数据加载完成后,可以确保第一次 render 时 useForm 的 defaultValues 已经有值。
import React, { useEffect, useState } from 'react';
import { useForm } from 'react-hook-form';
import { useStore } from './store';
function MyForm() {
const [loadedData, setLoadedData] = useState(null);
const { register, reset } = useForm();
const fetchData = useStore(state => state.fetchData);
useEffect(() => {
// 假设 fetchData 是一个异步函数,负责从 API 或 store 加载数据
const loadInitialData = async () => {
const data = await fetchData();
setLoadedData(data);
reset(data); // 数据加载后重置表单
};
loadInitialData();
}, [fetchData, reset]);
if (!loadedData) return <div>Loading...div>; // 数据加载前显示加载状态
return (
<form>
<input {...register("field1")} />
<input {...register("field2")} />
{/* 其他表单字段 */}
form>
);
}
这里是一个使用 zustand 创建的 fetchData 方法示例,用于从 API 或其他数据源加载数据并存储在 zustand 的状态中。
zustand Store 示例
import create from 'zustand';
import axios from 'axios'; // 用于发起 HTTP 请求的库,可以根据需要替换为其他库
const useStore = create((set) => ({
data: null, // 用于存储数据的初始状态
// fetchData 是一个异步函数,用于从 API 加载数据并更新状态
fetchData: async () => {
try {
const response = await axios.get('/api/endpoint'); // 替换为你的 API 端点
const data = response.data;
set({ data }); // 将数据存储到 Zustand 状态中
return data; // 返回数据,方便在调用方处理
} catch (error) {
console.error('Failed to fetch data:', error);
return null; // 错误处理,返回 null 或者其他默认值
}
},
}));
export default useStore;
在组件中使用 fetchData
使用上面的 useStore 中的 fetchData 函数,你可以在组件中调用它来获取数据并更新表单的默认值:
import React, { useEffect, useState } from 'react';
import { useForm } from 'react-hook-form';
import useStore from './store'; // 引入刚刚创建的 Zustand store
function MyForm() {
const [loadedData, setLoadedData] = useState(null);
const { register, reset } = useForm();
const fetchData = useStore(state => state.fetchData);
useEffect(() => {
// 使用 store 中的 fetchData 函数获取数据
const loadInitialData = async () => {
const data = await fetchData();
setLoadedData(data);
if (data) {
reset(data); // 数据加载后重置表单
}
};
loadInitialData();
}, [fetchData, reset]);
if (!loadedData) return <div>Loading...div>; // 数据加载前显示加载状态
return (
<form>
<input {...register("field1")} />
<input {...register("field2")} />
{/* 其他表单字段 */}
form>
);
}
export default MyForm;
详细说明
zustand Store:
组件中的使用:
异步加载和更新:
这个示例展示了如何通过 zustand 的 store 来管理 API 数据获取和表单状态的同步。如果需要处理更复杂的情况,比如错误处理或加载状态,亦可在 useEffect 中添加更多逻辑。
方法三:使用 useForm 的 defaultValues 动态初始化
在 useForm 初始化时直接使用 zustand store 中的状态,如果数据可能为 null 或未定义,你可以在初始化时提供一个默认值。
import React from 'react';
import { useForm } from 'react-hook-form';
import { useStore } from './store';
function MyForm() {
const data = useStore(state => state.data);
const { register } = useForm({
defaultValues: data || { field1: '', field2: '' }, // 设置默认值,防止第一次渲染时为 undefined
});
if (!data) return <div>Loading...div>;
return (
<form>
<input {...register("field1")} />
<input {...register("field2")} />
{/* 其他表单字段 */}
form>
);
}
总结
这几种方法都可以确保 defaultValues 在第一次渲染时有值,你可以根据具体需求选择合适的方案。
写作不易,如果觉得对你有用,请点个赞赞, 感谢支持~~