Подтвердить что ты не робот

ReactJS - как передать "глобальные" данные глубоко вложенным дочерним компонентам?

Как люди обычно подходят к "глобальным" данным в приложении React?

Например, скажем, у меня есть следующие данные для пользователя после входа в мое приложение.

user: {
  email: '[email protected]',
  name: 'John Doe'
}

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

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

<App>
  <Page1/>
  <Page2>
    <Widget1/>
    <Widget2 user={user}/>
  </Page2>
</App>

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

Существует ли способ управления этим типом данных React?

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

EDIT: я знаю, что по умолчанию вызов setState на моем компоненте верхнего уровня приведет к повторному отображению всех дочерних компонентов, и что в каждом дочернем компоненте я могу отображать, используя любые данные, которые мне нравятся (например, глобальные данные, а не только состояние или реквизит). Но как люди выбирают, чтобы уведомлять только определенные дочерние компоненты, которые они должны отображать?

4b9b3361

Ответ 1

Поскольку я первоначально ответил на этот вопрос, для меня стало очевидным, что сам React не поддерживает "глобальные" данные в каком-либо смысле - он действительно предназначен для управления пользовательским интерфейсом и тому подобным. Данные вашего приложения должны жить где-то еще. Сказав это, он теперь поддерживает доступ к глобальным context данным, как подробно описано в этом другом ответе на этой странице. Этот репозиторий (неустановленного) якобы оборачивает context в более удобном пути, для тех, кто заинтересован, и здесь хорошую статью Кент Доддс о том, как context апи эволюционировала, и теперь официально поддерживается в React.

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

  • Сами Facebook решают эту проблему, используя собственную библиотеку Flux.
  • Mobx и Redux похожи на Flux, но, похоже, более популярны. Они делают то же самое, но более понятным и интуитивно понятным способом.

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

СТАРЫЙ ОТВЕТ:


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

https://github.com/dustingetz/react-cursor

и эта похожая библиотека:

https://github.com/mquan/cortex

ОСНОВНОЕ ПРИМЕЧАНИЕ: Я думаю, что это работа для Facebook Flux, или что-то подобное (что выше). Когда поток данных становится слишком сложным, требуется другой механизм для связи между компонентами, отличными от обратных вызовов, и Flux и его клоны, по-видимому, являются им...

Ответ 2

Используйте React Context Property Это специально для передачи глобальных наборов данных по цепочке без явной пересылки. Это усложняет функции жизненного цикла компонента, и обратите внимание на предостережения, предлагаемые на странице, с которой я связан.

Ответ 3

Вы можете использовать React Context API для передачи глобальных данных в глубоко вложенные дочерние компоненты. Кент К. Доддс написал об этом обширную статью о Medium Reacts - новом Context API. Это поможет лучше понять, как использовать API.

Ответ 4

Что не так, просто передавая данные по всей цепочке компонентов путем рендеринга всех дочерних элементов с помощью {... restOfProps}?

render(){
  const {propIKnowAbout1, propIKnowAbout2, ...restOfProps} = this.props;
  return <ChildComponent foo={propIKnowAbout1} bar={propIKnowAbout2} {...restOfProps}/>
}