Подход к переключению компонентов react между подкомпонентами с помощью формы

#reactjs #forms #components

#reactjs #формы #Компоненты

Вопрос:

В настоящее время я занимаюсь своим первым проектом FE, который я должен создать полностью самостоятельно.

У меня есть компонент, который должен содержать 3 подкомпонента, каждый из которых должен отображать форму.

В настоящее время я выбрал подход, которым я был очень доволен, но затем я начал думать о тестировании, и я понял, что я в принципе не могу создать тест для родительского компонента без зависимости от дочерних компонентов. Родительский компонент выглядит примерно так:

 return (
<div className="personal-data-step-wrapper">
  {currentForm === 0 amp;amp; <UserDataForm handleChangeForm={handleChangeForm}
                                      setValues={setUserDataFormValues}
                                      defaultValues={userDataFormValues}/>}
  {currentForm === 1 amp;amp; <CertificateDataForm handleChangeForm={handleChangeForm}
                                             setValues={setCertificateDataFormValues}
                                             defaultValues={certificateDataFormValues}/>}
  {currentForm === 2 amp;amp; <QSCDDeviceDataForm onStepFinish={onFinish}
                                            handleChangeForm={handleChangeForm}
                                            setValues={setQSCDeviceDataFormValues}
                                            defaultValues={qSCDDeviceDataFormValues}/>}
</div>
)
 

А затем в дочернем компоненте:

 const onFinish = () => {
setValues({
  documentType: form.getFieldValue("documentType"),
  documentIssueDate: form.getFieldValue("documentIssueDate"),
  documentFullName: form.getFieldValue("documentFullName"),
  documentNumber: form.getFieldValue("documentNumber"),
  documentAddress: form.getFieldValue("documentAddress")
})
handleChangeForm(1)
}
 

Вы можете видеть, что переключение между формами выполняется в дочерних компонентах после успешной отправки или при переключении на предыдущую форму. После отправки последней формы родительский компонент собирает данные всех дочерних форм в единый объект и вызывает с ним функцию интерфейса репозитория.

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

Итак, мой вопрос: как я должен справиться с такой задачей? Правильный ли мой подход или он фундаментально неправильный?

Спасибо за все предложения и ответы..

Ответ №1:

Я думаю, довольно очевидно, что вы должны вызывать свой handleChangeForm() из своего родительского компонента, например:

а) если это компонент класса

 componentDidUpdate(prevProps, prevState) {
    if (this.state.currentForm !== prevState.currentForm)
        this.handleChangeForm(this.state.currentForm);
}
 

б) если это функциональный компонент

 useEffect(() => {
    handleChangeForm(currentForm);
}, [currentForm]);
 

Я предположил, что changeForm это значение состояния, но в любом случае вы поняли идею…

Редактировать

Если вы хотите исключить логику изменения формы из дочерних элементов, вы можете переместить кнопку «далее» на родительский элемент. Таким образом, вы просто спросите соответствующего дочернего элемента, действительны ли входные данные формы, и если дочерний элемент подтвердит — продолжайте и измените форму изнутри родительского элемента.

То, что вы просили, — это протестировать эту логику без включения дочерних элементов. И это было бы вполне возможно, вы бы просто издевались над «подтверждением» от дочерних элементов (например, простое true / false).

Комментарии:

1. Спасибо за ответ. У меня появилась идея, но я не уверен, как вызвать изменение компонента в родительском компоненте, когда кнопки, используемые для изменения форм, содержатся в дочерних компонентах. Метод handleChangeForm — это метод, который вызывает setCurrentForm (установщик значений состояния), проверяя, находится ли значение в определенном диапазоне. В настоящее время мой подход просто отправляет установщик handleChangeForm в качестве опоры дочернему компоненту, а дочерний компонент вызывает handleChangeForm при нажатии кнопки отправки.

2. Если и метод, и значение состояния находятся в вашем родительском компоненте, я не вижу здесь проблемы…

3. Я хочу, чтобы родительский компонент был как можно более независимым от дочерних компонентов (возможно, это неправильный подход). Поэтому, когда я создаю тест, я хочу переключаться между всеми тремя возможными состояниями currrentForm, даже не зная, что дочерние элементы были отображены, что сейчас невозможно, потому что мне нужно найти кнопку продолжения, которая является частью дочернего компонента. Моей первой идеей было поместить кнопки управления в родительскую форму, но таким образом я не могу вызвать проверки дочерних форм, что помешало бы мне перейти к следующей форме, если данные были недействительными. Итак, как вы думаете, я должен вызвать handleChangeForm в моем тесте?

4. Спасибо, это действительно похоже на идею, которой я был бы доволен. Я думал об этом раньше, но как мне запросить подтверждение у дочерних элементов? Мне как-то нужно было бы вызвать функцию form.submit, которая затем передавала бы статус результата отправки в родительский компонент. Я пришел только с решением, в котором я бы передал логическое значение состояния «submit» дочернему элементу, а затем в дочернем элементе я бы использовал useEffect с условием отправки значения, которое в случае истинного значения вызывало бы form.submit , а затем мне нужно было бы передать параметр установки значения состояния, который отправил бырезультат в родительский. Вы знаете лучший способ?

5. Если вам нужна дополнительная помощь, опубликуйте свою логику проверки (реализацию)