• 作者:老汪软件技巧
  • 发表时间: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 在第一次渲染时有值,你可以根据具体需求选择合适的方案。

写作不易,如果觉得对你有用,请点个赞赞, 感谢支持~~