ReactNative componentDidMount не вызывается - PullRequest
0 голосов
/ 24 октября 2018

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

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

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

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


РЕДАКТИРОВАТЬ:

Вот код

Экран A

Функция обработчика, которая вызывается при сканировании 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 вызывается только при первом прохождении маршрута.

Ответы [ 3 ]

0 голосов
/ 25 октября 2018

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

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

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

У меня возникла похожая проблема, и я использовал 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.

0 голосов
/ 24 октября 2018

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

Я рекомендую передать обратный вызов методу setOnNavigatorEvent вашегонавигатор с событием didAppear.Ваш обратный вызов будет вызываться при каждом событии, генерируемом реагировать на встроенную навигацию, и вы можете проверять свою логику каждый раз, когда появляется экран (отсюда и использование события 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
    }
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...