ReactJS — Как дочерний элемент может найти своего родителя?

#javascript #facebook #reactjs

#javascript #Facebook #reactjs

Вопрос:

Есть ли в ReactJS способ для компонента выяснить, кто его родитель?

РЕДАКТИРОВАТЬ 1: Независимо от преимуществ этого, есть ли способ?

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

Я попытался установить свойство «owner», и эта идея, похоже, работает, но мне интересно, каков наилучший подход?

например

 <Parent>
  <Child owner={this}/>
</Parent>
  

Затем в дочернем компоненте я могу сделать owner.method , и, похоже, он работает нормально. Я знаю, что это не настоящие отношения родитель / потомок, но это самое близкое, что я нашел в своих тестах.

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

РЕДАКТИРОВАТЬ 2: значит, это невозможно?

Что мне не нравится в идее, что она не поддерживается, так это то, что HTML может быть помечен нулевым javascript — и это подразумевает функциональность по умолчанию — некоторые элементы должны иметь родителей — они определяются как дочерние элементы других элементов (например, ul и li). Этого не может произойти в JSX, потому что, если есть взаимодействие между элементами — должны быть события javascript, которые связывают компоненты вместе — каждый раз, когда вы их используете. Дизайнеры не могут просто написать синтаксис, подобный HTML, — кто-то должен вмешаться и вставить туда некоторые привязки javascript, что усложняет обслуживание. Я думаю, что идея имеет смысл для переопределения поведения по умолчанию, но поведение по умолчанию должно поддерживаться. И по умолчанию потребуется знать либо вашего родителя, либо кто ваш владелец.

Ответ №1:

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

TL; DR вы, вероятно, никогда не захотите этого делать.

Допустим, наш RadioButton имеет этот общедоступный интерфейс:

 <RadioButton active={true} onSelect={function(event){}}>text</RadioButton>
  

Мы могли бы создать другой компонент с именем SuperRadioButton, который мог бы иметь другой способ представления, но при этом иметь тот же общедоступный API, что и RadioButton, поэтому он является допустимым дочерним элементом RadioButtonGroup .

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

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

1. привет… спасибо за отзыв! Я понимаю плюсы / минусы этого и готов создавать пользовательские композиты для каждого раза, когда я хочу делать подобные вещи, что снимает основную проблему с этим — поэтому я думаю, что первоначальный вопрос все еще остается в силе — есть ли чистый способ реагирования на получение родительских компонентов?

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

3. @BradParks Я согласен с FakeRain. Если вы оказались в ситуации, когда вам нужно получить доступ к родительскому компоненту, вы, скорее всего, используете антишаблон или вам нужно улучшить дизайн своего приложения. Предоставление обратных вызовов в качестве реквизитов обычно является способом взаимодействия между компонентами.

4. «Есть некоторые разговоры о раскрытии свойства owner». Я не слышал никаких разговоров об этом.

5. Итак…. Я думаю, что тогда это невозможно сделать, правильно 😉 Кроме того, что я уже делаю?

Ответ №2:

Обратные вызовы. Свойства владельца. Передача событий для перехвата корнем в дереве. Передача корня вниз через контексты.

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

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

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

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

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

1. спасибо за отзыв — я не хочу, чтобы мои дети мутировали за пределами знаний родителей — я просто хочу, чтобы мой дочерний элемент мог уведомлять своего родителя о том, что он должен изменить свое состояние, то есть состояние родителей, которое затем будет передано дочернему элементу. Конечно, я могу сделать это с обратными вызовами, но тогда мой HTML, подобный JSX, — это HTML с javascript, который меньше похож на HTML… Если бы мой дочерний элемент мог звонить parent.selectChild(childIndex) , у меня могли бы быть автоматические «реакции»