Что бы вы сделали, чтобы сделать эту форму React + компонент Formik более читабельной?

Я создал простую страницу с формой реакции, используя formik и YUP. Поскольку мне нужно загрузить данные для заполнения выпадающих полей перед загрузкой страницы, я вызываю некоторые API, используя библиотеку response-query.

Я заметил, что форма отображается 4 раза до завершения загрузки страницы. Я не очень хорошо знаком с реакцией, поэтому мне хотелось бы узнать, что можно было бы сделать лучше, чтобы улучшить этот код для дальнейшего использования.

введите описание изображения здесь

import { useFormik } from 'formik'
import React, { useEffect } from 'react'
import { useQuery } from 'react-query'
import { useParams } from 'react-router-dom'
import Button from '../../../components/Button'
import { ImageRounded } from '../../../components/ImageRounded'
import PageHeader from '../../../components/PageHeader'
import PageTitle from '../../../components/PageTitle'
import { formatDate } from '../../../helpers/DateHelpers'
import { hasMedicalRole, hasRole } from '../../../helpers/EnumHelpers'
import useLoader from '../../../hooks/UseLoader'
import { getUserById } from '../../../services/UserService'
import InputMask from 'react-input-mask'
import * as Yup from 'yup';
import { getActiveRoles, getBiologicalSexs, getMedicalRegistryCouncils, getStates } from '../../../services/EnumService.js'

const FormErrorLabel = ({ formik, field }) => {
    return formik.touched[field] && formik.errors[field] ? (

        <label className="error">{formik.errors[field]}</label>

    ) : null;
}

const EditUserPage = ({ }) => {
    const params = useParams();
    const { loading, setLoading } = useLoader();
    const { isLoading, error, data } = useQuery('getUserById', () => getUserById(params.id))
    const { isLoading: isloadingBiologicalSexs, error: errorBiologicalSexs, data: dataBiologicalSexs } = useQuery('getBiologicalSexs', () => getBiologicalSexs())
    const { isLoading: isloadingStates, error: errorStates, data: dataStates } = useQuery('getStates', () => getStates())
    const { isLoading: isloadingMedicalRegistryCouncils, error: errorMedicalRegistryCouncils, data: dataMedicalRegistryCouncils } = useQuery('getMedicalRegistryCouncils', () => getMedicalRegistryCouncils())
    const { isLoading: isloadingActiveRoles, error: errorActiveRoles, data: dataActiveRoles } = useQuery('getActiveRoles', () => getActiveRoles())

    const user = data?.data?.result;
    const biologicalSexs = dataBiologicalSexs?.data?.result;
    const states = dataStates?.data?.result;
    const medicalRegistryCouncils = dataMedicalRegistryCouncils?.data?.result;
    const activeRoles = dataActiveRoles?.data?.result;

    const formik = useFormik({
        enableReinitialize: true,
        initialValues: user ? {
            ...user,
            birthdate: formatDate(user.birthdate)
        } : {},
        validationSchema: Yup.object({
            fullName: Yup.string()
                .required('É preciso informar o nome'),
            login: Yup.string()
                .required('É preciso informar o login'),
            birthdate: Yup.string()
                .test('dateRequired', 'É preciso informar a data de nascimento', (val) => {
                    if (!val) return false;

                    return val.replace(/[^0-9]+/g, '').length > 0;
                }),
            email: Yup.string()
                .required('É preciso informar o e-mail')
                .email('É preciso informar um e-mail válido'),
            documentNumber: Yup.string()
                .required('É preciso informar o número do documento'),
        }),
        onSubmit: values => {

            alert(JSON.stringify(values, null, 2));
        },
    });

    useEffect(() => {

        setLoading(isLoading || isloadingBiologicalSexs || isloadingStates || isloadingMedicalRegistryCouncils || isloadingActiveRoles);

    }, [isLoading, isloadingBiologicalSexs, isloadingStates, isloadingMedicalRegistryCouncils, isloadingActiveRoles]);

    if (error) {
        return (<h1>Erro: {JSON.stringify(error.message)}</h1>)
    }

    return (
        user && biologicalSexs && biologicalSexs && states && medicalRegistryCouncils && activeRoles &&
        <>
            <div className="row">
                <div className="col-12">
                    <PageHeader>
                        <PageTitle icon="fal fa-user" text="Editar usuário" subtext="Edite as informações do usuário no sistema" />
                    </PageHeader>
                </div>
            </div>

            <form onSubmit={formik.handleSubmit}>
                <div className="row mt-3">
                    <div className="col-2">
                        <ImageRounded src={user.profilePicture} alt="foto do usuário" title="foto do usuário" />
                    </div>
                </div>

                <div className="form-group mt-3">
                    <div className="pretty p-switch p-fill">
                        <input name="isActive"
                            type="checkbox"
                            onChange={formik.handleChange}
                            onBlur={formik.handleBlur}
                            value={formik.values.isActive}
                            checked={formik.values.isActive} />

                        <div className="state p-primary">
                            <label>&nbsp;Ativo</label>
                        </div>
                    </div>
                </div>

                <div className="form-group mt-3">
                    <label>Nome Completo</label>
                    <input
                        className="form-control"
                        name="fullName"
                        placeholder="Digite um nome"
                        type="text"
                        onChange={formik.handleChange}
                        onBlur={formik.handleBlur}
                        value={formik.values.fullName} />

                    <FormErrorLabel formik={formik} field={'fullName'} />
                </div>
                <div className="form-group mt-3">
                    <label>Login</label>

                    <input
                        className="form-control disable-autofill"
                        name="login"
                        placeholder="Digite um nome de login"
                        type="text"
                        onChange={formik.handleChange}
                        onBlur={formik.handleBlur}
                        value={formik.values.login} />

                    <FormErrorLabel formik={formik} field={'login'} />
                </div>

                <div className="form-group mt-3">
                    <label>Nascimento</label>

                    <InputMask
                        className="form-control datepicker"
                        mask="99/99/9999"
                        autoComplete="off"
                        name="birthdate"
                        onChange={formik.handleChange}
                        onBlur={formik.handleBlur}
                        value={formik.values.birthdate} />

                    <FormErrorLabel formik={formik} field={'birthdate'} />
                </div>

                <div className="form-group mt-3">
                    <label className="control-label" style={{ display: 'block' }}>Sexo</label>

                    <select
                        className="form-control"
                        name="biologicalSexId"
                        onChange={formik.handleChange}
                        onBlur={formik.handleBlur}
                        value={formik.values.biologicalSexId}
                    >
                        {Object.keys(biologicalSexs).map(key => {
                            return (<option key={key} value={key}>{biologicalSexs[key]}</option>)
                        })}
                    </select>

                    <FormErrorLabel formik={formik} field={'biologicalSex'} />
                </div>
                <div className="form-group mt-3">
                    <label>Endereço de Email</label>

                    <input
                        className="form-control disable-autofill"
                        name="email"
                        placeholder="Digite um email"
                        type="text"
                        onChange={formik.handleChange}
                        onBlur={formik.handleBlur}
                        value={formik.values.email}
                    />

                    <FormErrorLabel formik={formik} field={'email'} />
                </div>

                <div className="form-group mt-3">
                    <label>CPF</label>

                    <InputMask
                        className="form-control cpf"
                        mask="999-999-999-99"
                        autoComplete="off"
                        name="documentNumber"
                        placeholder="Digite seu CPF"
                        onChange={formik.handleChange}
                        onBlur={formik.handleBlur}
                        value={formik.values.documentNumber} />

                    <FormErrorLabel formik={formik} field={'documentNumber'} />
                </div>

                <div className="mt-3">
                    <label style={{ display: 'block' }}>Perfis de acesso</label>

                    {Object.keys(activeRoles).map(key => {
                        return (
                            <div key={key} className="pretty p-icon p-curve p-pulse">
                                <input
                                    type="checkbox"
                                    name="roles"
                                    onChange={formik.handleChange}
                                    onBlur={formik.handleBlur}
                                    value={key}
                                    defaultChecked={hasRole(user.roles, key)} />

                                <div className="state p-primary">
                                    <i className="icon fas fa-check"></i>
                                    <label>{activeRoles[key]}</label>
                                </div>
                            </div>)
                    })}
                </div>

                {hasMedicalRole(user.roles) &&
                    <section className="mt-3">
                        <div className="row">
                            <div className="col-md-4">
                                <div className="form-group">
                                    <label>Registro</label>

                                    <select
                                        className="form-control"
                                        name="medicalRegistryTypeId"
                                        onChange={formik.handleChange}
                                        onBlur={formik.handleBlur}
                                        value={formik.values.medicalRegistryTypeId}>
                                        <option >Selecionar registro</option>

                                        {Object.keys(medicalRegistryCouncils).map(key => {
                                            return (<option key={key} value={key}>{medicalRegistryCouncils[key]}</option>)
                                        })}
                                    </select>

                                    <FormErrorLabel formik={formik} field={'medicalRegistryTypeId'} />
                                </div>
                            </div>

                            <div className="col-md-4">
                                <div className="form-group">
                                    <label>Nº</label>

                                    <input
                                        className="form-control number"
                                        name="medicalRegistryNumber"
                                        placeholder="Nº do documento"
                                        type="text"
                                        onChange={formik.handleChange}
                                        onBlur={formik.handleBlur}
                                        value={formik.values.medicalRegistryNumber} />

                                    <FormErrorLabel formik={formik} field={'medicalRegistryNumber'} />
                                </div>
                            </div>

                            <div className="col-md-4">
                                <div className="form-group">
                                    <label>Estado emissor</label>

                                    <select
                                        className="form-control"
                                        name="medicalRegistryStateId"
                                        onChange={formik.handleChange}
                                        onBlur={formik.handleBlur}
                                        value={formik.values.medicalRegistryStateId}>

                                        {Object.keys(states).map(key => {
                                            return (<option key={key} value={key}>{states[key]}</option>)
                                        })}
                                    </select>

                                    <FormErrorLabel formik={formik} field={'medicalRegistryStateId'} />
                                </div>
                            </div>
                        </div>

                        <div className="row mt-3">
                            <div className="col-md-12">
                                <div className="form-group mt-3">
                                    <div className="pretty p-switch p-fill">
                                        <input name="prescriptionType" type="radio" value="1" />

                                        <div className="state p-primary">
                                            <label>&nbsp;Usar receita padrão</label>
                                        </div>
                                    </div>
                                    <br />
                                    <small className="text-muted">
                                        Essa opção faz com que a área de receituário do prontuário vem a busca de medicamentos padrão do
                                        smzero
                                    </small>
                                </div>

                                <div className="form-group mt-3">
                                    <div className="pretty p-switch p-fill">
                                        <input name="prescriptionType" type="radio" value="2" />

                                        <div className="state p-primary">
                                            <label>&nbsp;Usar receita com texto livre</label>
                                        </div>
                                    </div>
                                    <br />
                                    <small className="text-muted">
                                        Essa opção faz com que a área de receituário do prontuário vem com pesquisa de medicamento
                                    </small>
                                </div>

                                <div className="form-group mt-3">
                                    <div className="pretty p-switch p-fill">
                                        <input name="prescriptionType" type="radio" value="3" />

                                        <div className="state p-primary">
                                            <label>&nbsp;Usar receita com certificado digital</label>
                                        </div>
                                    </div>
                                    <br />
                                    <small className="text-muted">
                                        Essa opção faz com que a área de receituário do prontuário permite a assinatura digital
                                    </small>
                                </div>
                            </div>
                        </div>
                    </section>
                }

                <div className="form-group mt-5">
                    <Button color="primary" rounded={true}>Cadastrar usuário</Button>
                </div>
            </form>
        </>
    )
}

export default EditUserPage

0

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *