реакция-навигация: обнаружение, когда экран, панель активирована/отображается/фокус/размытие

Вначале, когда я хотел сделать некоторые действия при открытии экрана, я поместил их внутри componentDidMount. Например, я могу получить некоторые данные.

как это.

componentDidMount() {
  this.updateData();
}

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

Каков правильный способ обнаружения, когда страница (экран) активирована и выполняет действия?

Ответ 1

С помощью react-navigation вы можете сделать это.

  1. Добавьте слушателей в componentDidMount или componentWillMount

    this.subs = [
      this.props.navigation.addListener('didFocus', (payload) => this.componentDidFocus(payload)),
    ]; 
    

    или же

    this.subs = [
      this.props.navigation.addListener('didFocus', this.componentDidFocus),
      this.props.navigation.addListener('willBlur', this.componentWillBlur),
    ];
    

    Затем вы можете сделать что-нибудь в componentDidFocus, например, выборку данных, обновление данных,...

  2. В componentWillUnmount удалите слушателей

    componentWillUnmount() {
      this.subs.forEach(sub => sub.remove());
    }
    

Для получения более подробной информации см. Этот PR: https://github.com/react-navigation/react-navigation/pull/3345

Обновленный 3.x:

addListener - Подписаться на обновления для жизненного цикла навигации

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

  • willBlur - экран будет не сфокусированным

  • willFocus - экран будет фокусироваться

  • didFocus - экран сфокусирован (если был переход, переход завершен)

  • didBlur - экран не сфокусирован (если был переход, переход завершен)

Ссылка: https://reactnavigation.org/docs/en/navigation-prop.html#addlistener-subscribe-to-updates-to-navigation-lifecycle

Обновленный пример 3.x:

const didBlurSubscription = this.props.navigation.addListener(
  'didBlur',
  payload => {
    console.debug('didBlur', payload);
  }
);

// Remove the listener when you are done
didBlurSubscription.remove();

Полезная нагрузка JSON:

{
  action: { type: 'Navigation/COMPLETE_TRANSITION', key: 'StackRouterRoot' },
  context: 'id-1518521010538-2:Navigation/COMPLETE_TRANSITION_Root',
  lastState: undefined,
  state: undefined,
  type: 'didBlur',
};

Ответ 2

componentDidMount/componentWillUnmount работает не во всех случаях навигации (например, вкладки).

Вам нужно использовать addListener с событиями didFocus и didBlur для выполнения таких действий. Подробности смотрите в документации.

Ответ 3

Это может быть поздно, но я так решил. Смотрите код ниже. Не забудьте импортировать с помощью Navigation и обернуть экспорт по умолчанию с помощью Navigation.

import { withNavigation } from "react-navigation";
 componentDidMount() {
    const { navigation } = this.props;
    this.focusListener = navigation.addListener("didFocus", () => {
      // The screen is focused
      // Call any action
    });
  }

  componentWillUnmount() {
    // Remove the event listener
    this.focusListener.remove();
  }

export default withNavigation(Your Class Name);

Ответ 4

Возможно, попробуйте componentDidUpdate и установите состояние внутри вашего компонента. Когда состояние изменяется, происходит повторная реновация

Ответ 5

NavigationEvents - это еще один способ добавить прослушиватель событий прямо в JSX. Подробности смотрите в документации.

Это выглядит примерно так:

import { NavigationEvents } from 'react-navigation';

return (
  <ScrollView style={styles.container}>
    <NavigationEvents            
      onDidBlur={payload => console.log('did blur', payload)}
    />
    {this.props.children}
  </ScrollView>
);