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

Я использую реакцию-native с реакцией-native-navigation. Я хотел бы перезагрузить данные при отображении компонента. Компонент отображается, когда пользователь нажимает кнопку навигации на вкладке.

Должен ли я использовать события жизненного цикла реагирования или есть что-то в реакции-на-на-навигация, которые могут вызывать функцию, когда пользователь переходит к компоненту?

Я использую redux, я не уверен, что это можно использовать, чтобы помочь?

Эта проблема относится к onDisplay которая кажется тем, что я ищу. Однако я не могу найти официальную документацию об этом - https://github.com/wix/react-native-navigation/issues/130

Ответы

Ответ 1

Мне нравится решение, предложенное Бруно Рейсом. Я переделал мой, чтобы сделать его немного проще.

class Whatever extends Component {
    componentDidMount(){
        this.load()
        this.props.navigation.addListener('willFocus', this.load)
    }
    load = () => {
        ...
    }

}

Ответ 2

включите это как "callIfBackToThisRoute"...

export default ( props, call ) => {
    if( !props.navigation ) throw 'I need props.navigation'
    const thisRoute = props.navigation.state.routeName;
    props.navigation.addListener(
        'willFocus',
        payload => {
            if( payload.state.routeName == thisRoute) call(props)
        }
    );
}

и использовать его внутри вашего компонента...

componentDidMount() {
    const { doIt } = this.props;
    doIt()
    callIfBackToThisRoute(
        this.props,
        (props) => doIt()
    )
}

Ответ 3

Вот что я в итоге использовал:

export default class RootNavigator extends React.Component {
  state = {currentScreen: null}

  _onNavigationStateChange(prevState, newState, action) {
    // const currentScreen = getCurrentRouteName(currentState)
    // const prevScreen = getCurrentRouteName(prevState)
    // console.debug('onNavigationStateChange currentScreen=', currentScreen,
    //   'prevScreen=', prevScreen, 'action.routeName=', action.routeName)
    console.debug('onNavigationStateChange action.routeName=', action.routeName)
    this.setState({currentScreen: action.routeName})
  }

  render() {
    return <RootStackNavigator onNavigationStateChange={this._onNavigationStateChange.bind(this)}
      screenProps={{currentScreen: this.state.currentScreen}}/>;
  }

в сочетании с componentDidUpdate() на экране (который может или не может выполнять что-либо в зависимости от экрана currentScreen).

Примечание. Я не знаю, что/где getCurrentRouteName() есть, и он дал ошибку для меня, поэтому я не использую его и напрямую использую action.routeName.

См. Https://github.com/react-community/react-navigation/issues/2371 и https://github.com/react-community/react-navigation/issues/51#issuecomment-323536642 для получения дополнительной информации и обсуждения.

Ответ 4

Для RNN v3, после нескольких попыток, я наконец нашел правильный путь:

  componentDidMount() {
    this.navigationEventListener = Navigation.events().bindComponent(this);
  }

  componentWillUnmount() {
    if (this.navigationEventListener) {
      this.navigationEventListener.remove();
    }
  }

  componentDidAppear() {   // Lazy loading data for RNN
    if (this.state.routes.length === 0) {
      this.getData();
    }
  }

Ключ заключается в том, что привязка прослушивателя событий является обязательной, в противном случае componentDidAppear() и componentDidDisappear() не будут запущены.