Обновление: это решение больше не работает, поскольку React Native не включает стандартную библиотеку Node. Однако есть автономные модули, в которых реализован API EventEmitter. Рассмотрите возможность проверки eventemitter3 и tiny-emitter.

В последнее время я часто сталкивался с интересным паттерном при разработке своих приложений: вам нужно запустить определенный блок кода в компоненте A, реагируя на изменение в компоненте B. Например, при нажатии на компонент A компонент B должен анимировать имущество. Если оба являются братьями и сестрами (вы не можете передать функцию для обновления B из A) и учитывая, что вы не можете задействовать redux (поскольку мы говорим об анимации), вам нужно остановиться и подумать.

Я несколько раз видел, как реализовал следующую стратегию: когда компонент B изменяется, он обновляет логическое значение, которое определяет, должен ли выполняться блок кода в A. Когда логическое значение истинно, блок запускается, сразу же снова устанавливая для него значение false.

Это ужасная стратегия, добавляющая кучу ненужного кода. Понятно, что в этом случае мы хотим испускать события. А поскольку React Native зависит от Node.js, мы можем использовать фантастический EventEmitter от Node. Подробнее об этом можно прочитать здесь.

Во-первых, мы, очевидно, должны его импортировать:

import EventEmitter from 'events';

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

constructor(props) {
  super(props);
  this._emitter = new EventEmitter();
}

Вы можете удалить слушателей по отдельности, но лучше всего удалить их все при размонтировании компонента:

componentWillUnmount() {
  this._emitter.removeAllListeners();
}

Теперь вы можете передать этот эмиттер через реквизит.

<ComponentA emitter={this._emitter} />

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

this.props.emitter.emit('eventName');

В компоненте B мы должны установить слушателя как таковой:

componentWillMount() {
  this.props.emitter.addListener('eventName', () => {
    // this block of code executes when 'eventName' is emitted
  });
}

Заключение:

Узел EventEmitter - это мощный API, и я определенно рекомендую вам прочитать документацию, поскольку я лишь поверхностно рассмотрел, как это работает.

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