reactjs - 从父 React 组件状态继承的 Formik initialValues 的异步更新(利用 useEffect 挂钩?)
问题描述
我目前正在用户入职过程中构建一个多步骤表单,这就是为什么我需要将所有表单数据集中在父 React 组件状态中的原因。
我需要使用用户信息更新 initialValues,但这是一个异步过程。
我想创建一个调用 setState 的 useEffect 钩子,但也许有一种更优雅的方法......
将 initialValues 作为 useEffect 依赖项之一似乎会创建一个无限循环 ( Maximum update depth exceeded
)。这就是为什么我找到的工作解决方案是在...中复制所有初始值
那么在获取异步用户信息后,如何仅更新 initialValues 中的特定值呢?
这是实现的简化版本:
import React, { useState, useEffect } from 'react'
// Auth0 hook for authentication (via React Context).
import { useAuth0 } from '../../contexts/auth/auth'
import { Formik, Form, Field } from 'formik'
export default () => {
const { user } = useAuth0()
const initialValues = {
profile: {
name: '',
address: '',
// Other properties...
},
personalInfo: {
gender: '',
birthday: '',
// Other properties...
},
}
const [formData, setFormData] = useState(initialValues)
const [step, setStep] = useState(1)
const nextStep = () => setStep((prev) => prev + 1)
useEffect(() => {
const updateInitialValues = (user) => {
if (user) {
const { name = '', gender = '' } = user
const updatedInitialValues = {
profile: {
name: name,
// All other properties duplicated?
},
personalInfo: {
gender: gender,
// All other properties duplicated?
},
}
setFormData(updatedInitialValues)
}
}
updateInitialValues(user)
}, [user, setFormData])
switch (step) {
case 1:
return (
<Formik
enableReinitialize={true}
initialValues={formData}
onSubmit={(values) => {
setFormData(values)
nextStep()
}}
>
<Form>
<Field name="profile.name" type="text" />
<Field name="profile.address" type="text" />
{/* Other fields */}
<button type="submit">Submit</button>
</Form>
</Formik>
)
case 2:
return (
<Formik
enableReinitialize={true}
initialValues={formData}
onSubmit={(values) => {
setFormData(values)
nextStep()
}}
>
<Form>
<Field name="personalInfo.gender" type="text" />
<Field name="personalInfo.birthday" type="text" />
{/* Other fields */}
<button type="submit">Submit</button>
</Form>
</Formik>
)
// Other cases...
default:
return <div>...</div>
}
}
解决方案
看到这个问题对我来说可能已经晚了,我最近恰好在做一个类似的项目。
对于我的用例,我只使用一个 Formik,并使用类似于 Formik 多步表单向导的理论:https ://github.com/formium/formik/blob/master/examples/MultistepWizard.js用于我的多步表单。
在每一步,我都需要获取 API 来预填充数据,我也使用 useEffect 但由于我只是在加载特定步骤时调用 API 一次,所以我强制它的行为与 ComponentDidMount() 相同,即离开[] 注释为空,// eslint-disable-next-line
因此不会给我警告。
成功加载数据后,我在 useEffect 中使用 setFieldValue 。我觉得我的也不是处理这种情况的好方法,我刚刚发现了一些可能有用的东西:https ://github.com/talor-hammond/formik-react-hooks-multi-step-form ,它有动态初始值。(虽然是打字稿)
我将参考这个并尝试在我的每个步骤中使用,并且可能使用 Context 或将它们包装在父级中并将数据存储在父级 Formik 中。
并且为您获得无限循环可能是因为setFormData
不应该在依赖项中,因为当您设置状态时,组件重新渲染,useEffect 再次调用。
不确定这是否可以帮助您,或者您已经知道如何实现它,我会更深入地研究它。
推荐阅读
- ios - Swift中的Objective C类方法调用
- java - 我的字符串末尾的最后一个字符 '\n' 已修改为空格字符
- c# - 在 ASP.NET Core 中连接子应用程序
- python-2.7 - Reportlab 上的 Appengine 图像 pdf
- 3d - 如何沿局部 x、y、z 轴平移?(戈多)
- uwp - Windows Developer Dashboard: No app listed in push notification
- c# - .NET Core DbContext Dependency Resolution Scope
- javascript - 调用路由后应用程序挂起?
- javascript - 无法使用 jQuery 更改 Kendo Dropdown 的值
- github - git merge master branch 发布分支问题