【发布时间】:2020-03-27 17:02:56
【问题描述】:
我目前正在用户入职过程中构建一个多步骤表单,这就是为什么我需要将所有表单数据集中在一个父 React 组件状态中。
我需要使用用户信息更新 initialValues,但这是一个异步过程。
我想过创建一个调用 setState 的 useEffect 钩子,但也许有更优雅的方式来做...
将 initialValues 作为 useEffect 依赖项之一似乎会创建一个无限循环 (Maximum update depth exceeded)。这就是为什么我找到的工作解决方案是在...内复制所有 initialValues ????
那么在获取异步用户信息后,如何仅更新 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>
}
}
【问题讨论】:
-
已经有解决方案了吗?
-
不幸的是,还没有... :-/
标签: reactjs setstate formik use-effect