Asyn c обновление начальных значений Formik, унаследованных от состояния родительского компонента React (используя хук useEffect?) - PullRequest
0 голосов
/ 27 марта 2020

В настоящее время я создаю многошаговую форму во время процесса адаптации пользователя, поэтому мне нужно централизовать все данные формы в состоянии родительского компонента React.

Мне нужно обновить initialValues ​​с информацией о пользователе, но это асинхронный c процесс.

Я думал о создании ловушки useEffect, вызывающей setState, но, возможно, есть более элегантный способ сделать это ...

Иметь initialValues ​​в качестве одного из Кажется, что зависимости useEffect создают бесконечное число l oop (Maximum update depth exceeded). Вот почему я обнаружил, что работающим решением было продублировать все initialValues ​​внутри ... ?

Так как же я могу обновлять только указанные c значения из initialValues ​​после получения асинхронной c информации о пользователе?

Вот упрощенная версия реализации:

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>
    }
}
...