Это анти-паттерн для вызова метода дочернего компонента из Parent в реакции и почему? - PullRequest
0 голосов
/ 12 января 2019

Я пытаюсь реализовать определенный компонент Wizard, который пользователь может использовать, используя приведенный ниже шаблон.

<Wizard {...wizardProps} onFinish={this.handleFinish}>
    <WizardStep onValidate={() => this.componentARef.isValid()}>
        <ComponentA onRef = { ref => (this.componentARef = ref)}/>
    </WizardStep>

    <WizardStep onValidate={() => this.componentBRef.isValid()}>
        <ComponentB onRef = { ref => (this.componentBRef = ref)}/>
    </WizardStep>

    <WizardStep onValidate={() => this.componentCRef.isValid()}>
        <ComponentC onRef = { ref => (this.componentCRef = ref)}/>
    </WizardStep>
</Wizard>

Теперь, учитывая реакцию, мы не можем / не должны вызывать метод дочернего компонента из родительского компонента. Здесь я хочу сохранить метод isValid в каждом компоненте, который будет вызываться из родительского компонента Wizard при нажатии кнопки Next/Finish. Реагировать способом предложить перенести состояние и логику на родительский компонент. Но таким образом я не смогу повторно использовать один и тот же компонент, например ComponentA в любом другом мастере или любом другом месте, или мне придется дублировать логику проверки в каждом родительском компоненте, который использует ComponentA. Используя ref или этот подход Я могу легко получить доступ к методу дочернего компонента (isValid).

На сегодняшний день (React версия 16.6) я не вижу никаких подводных камней, использующих этот шаблон по необходимости в реакции. С какой возможной проблемой я могу столкнуться, используя этот шаблон в реакции? И есть ли лучший вариант в этом конкретном примере, использующий метод isValid в компоненте step (например, ComponentA) для повторного использования?

Ответы [ 2 ]

0 голосов
/ 24 января 2019

Краткий ответ: С этим подходом в вашем сценарии все в порядке. Просто зайдите снова, когда ваш сценарий изменится.

Объяснение

Это не анти-паттерн в вашем сценарии. Это будет считаться анти-паттерном, если вы управляете поведением дочернего компонента через ref.

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

Например, React советует не заполнять штат из реквизита. Это верно, потому что тогда у вас есть два источника правды, и вам нужно синхронизировать их, иначе ваш компонент не будет работать должным образом. Но, если вы уверены, что ваши реквизиты (в частности, данные) не будут меняться, это больше не анти-паттерн, потому что вы теперь заполняете состояние из реквизитов, но затем продолжаете управлять только на уровне состояний.

0 голосов
/ 12 января 2019

Краткий ответ

Да.

Длинный ответ

С Реагирует на документацию по ссылкам :

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

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

Ссылки были созданы для доступа к DOM в определенных случаях использования (фокус, выделение текста, воспроизведение мультимедиа, сторонние библиотеки и т. Д.), Но их следует избегать при попытке заставить другие компоненты выполнять действия.

Так что, конечно, у вас может быть приложение React, которое работает при использовании ссылок для вызова метода дочернего компонента, но да, это очень анти-паттерн.

...