ReactNative componentDidMount не вызывается

У меня есть два экрана: A и B, подключенные к StackNavigator.

Экран A - это сканер QR-кода. Как только QR-код отсканирован, он переходит на экран B.

На экране B я выполняю вызов API, используя QR-код, который передается в качестве параметра навигации с экрана A. Я вызываю этот вызов API в componentDidMount.

Моя проблема: если я перейду от A к B, затем обратно к A, а затем снова к B, componentDidMount не вызывается, и у меня нет возможности вызвать вызов API.


Обновлено:

Вот код

Экран А

Функция-обработчик, которая вызывается при сканировании QR-кода:

handleQRCode = qrCode => {
    NavigationService.navigate('Decode', {qrCode});
};

Экран B

QR-код извлекается из параметров состояния навигации и используется для вызова API (startDecode) через redux.

componentDidMount() {
    qrCode = this.props.navigation.state.params.qrCode;
    this.props.startDecode(qrCode.data);
}

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

Вы можете поделиться фрагментом кода?

Jose Vf 24.10.2018 22:41

@JoseVf Я только что добавил код

user1971466 24.10.2018 23:03
Умерло ли Create-React-App?
Умерло ли Create-React-App?
В этом документальном фильме React.dev мы исследуем, мертв ли Create React App (CRA) и какое будущее ждет этот популярный фреймворк React.
Освоение React Native: Пошаговое руководство для начинающих
Освоение React Native: Пошаговое руководство для начинающих
React Native - это популярный фреймворк с открытым исходным кодом, используемый для разработки мобильных приложений. Он был разработан компанией...
В чем разница между react native и react ?
В чем разница между react native и react ?
React и React Native - два популярных фреймворка для создания пользовательских интерфейсов, но они предназначены для разных платформ. React - это...
От React к React Native: Руководство для начинающих по разработке мобильных приложений с использованием React
От React к React Native: Руководство для начинающих по разработке мобильных приложений с использованием React
Если вы уже умеете работать с React, создание мобильных приложений для iOS и Android - это новое приключение, в котором вы сможете применить свои...
Хуки React: что это такое и как их использовать
Хуки React: что это такое и как их использовать
Хуки React - это мощная функция библиотеки React, которая позволяет разработчикам использовать состояние и другие возможности React без написания...
1
2
4 483
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Это происходит потому, что компонент B монтируется только при первом обращении к нему, поэтому componentDidMount больше не будет вызываться.

Я рекомендую вам передать обратный вызов методу setOnNavigatorEvent вашего навигатора с событием didAppear. Ваш обратный вызов будет вызываться при каждом событии, генерируемом response-native-navigation, и вы можете проверять выполнение своей логики каждый раз, когда появляется экран (отсюда и использование события didAppear). Вы можете основывать свой код на следующем:

export default class ExampleScreen extends Component {
  constructor(props) {
    super(props);
    this.props.navigator.setOnNavigatorEvent(this.onNavigatorEvent.bind(this));
  }

  onNavigatorEvent(event) {
    if (event.id === 'didAppear') {
      // do API call here
    }
  }
}

Возможно, я ошибаюсь, но является ли эта версия Wix реактивной навигацией? Я не могу вызвать setOnNavigatorEvent в моем навигаторе стека

user1971466 24.10.2018 23:04

Да, это так. Проверьте документацию wix.github.io/react-native-navigation/#/…

Andre Knob 24.10.2018 23:05

Что происходит, когда вы пытаетесь его использовать?

Andre Knob 24.10.2018 23:06

«не функция». Я использую reactnavigation.org/docs/en/stack-actions.html

user1971466 24.10.2018 23:09

Это не от wix. По тегу «response-native-navigation» в вашем посте я подумал, что вы используете wix.

Andre Knob 24.10.2018 23:10

Приношу свои извинения, я должен был обратить внимание на теги. Я их обновил.

user1971466 24.10.2018 23:16
Ответ принят как подходящий

В react-navigation каждый экран остается смонтированным. Это означает, что когда вы вернетесь к B, вы могли изменить реквизиты, но componentDidMount уже был вызван при первом создании этого экрана.

Для вас доступны два варианта (AFAIK), которые могут справиться с этим делом:

  1. Вместо вызова this.props.navigation.navigate() вы можете использовать this.props.navigation.push, который создаст еще один экземпляр экран B, таким образом вызывая жизненный цикл componentDidMount React мероприятие.
  2. На экране B вы можете поймать событие, в котором его свойства изменились. Это может произойти в новом статическом событии жизненного цикла. getDerivedPropsFromState или это может быть сделано в ближайшее время не рекомендуется componentWillReceiveProps.

Я пробовал нажать вот так -> this.props.navigation.push ('Decode', {qrCode}), но componentDidMount по-прежнему не вызывается.

user1971466 24.10.2018 23:30

Я также не обязательно меняю реквизиты, когда перехожу на экран B, но я ожидаю, что он снова вызовет вызов API, чтобы обновить локальную копию

user1971466 24.10.2018 23:31

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

Asaf David 24.10.2018 23:37

относительно вашего второго ответа - Если вы не меняете реквизиты, вы просто показываете уже смонтированный экран B, поэтому componentDidMount не будет вызываться снова

Asaf David 24.10.2018 23:39

У меня возникла аналогичная проблема, и я использовал this.props.navigation.addListener() для ее решения. В принципе, принудительный вызов componentDidMount() может быть возможен, если снова нажать на тот же экран используя ключ (я не пробовал), но ваш стек также будет расти, что не оптимально. Итак, когда вы вернетесь к экрану, который уже находится в стеке, вы можете использовать addListener(), чтобы увидеть, не перефокусируется ли он, и вы можете скопировать свой код componentDidMount() здесь:

class MyClass extends Component {

  someProcess = () => {
    // Code common between componentDidMount() and willFocus()
  }

  componentDidMount() {
    this.someProcess();
  }

  willFocus = this.props.navigation.addListener(
    'willFocus',
    (payload) => {
      this.someProcess();
    }
  );

}

Когда MyClass вызывается в первый раз, вызывается componentDidMount. В других случаях, когда он все еще находится в стеке, но вместо этого просто получает фокус, вызывается addListener.

Другие вопросы по теме

Похожие вопросы

Собственная сборка React начала давать сбой, потому что Gradle не может найти Could not find play-services-basement
Диаграмма VictoryScatter не отображает компонент данных внутри области диаграммы в React Native
Как я могу переключиться на второй ввод, если первый будет выполнен в React Native
Выполнить навигацию по карточкам с помощью стационарного режима response-native-tab-view?
Как использовать linkWithCredential после удаления текущего пользователя?
Для подписания "appnameTest" требуется команда разработчиков. Выберите команду разработчиков в редакторе проекта. (в целевом 'appnameTest')
React Native, отлично работает при запуске iOS с поддержкой реагирования, вылетает при развертывании с помощью testflight
Response-native-video TypeError: undefined не является объектом
Пустой экран iOS с поддержкой React-native при первом запуске iPad под управлением iOS 12.0.1
Изображение эталонного xcassets React-Native iOS получает неправильный размер