Реактивно-навигационные штрихи иногда не работают - PullRequest
1 голос
/ 10 января 2020

Я надеюсь, что это известная проблема, так как я не могу предоставить многое для go, чтобы получить помощь в ее решении.

Я использую реагирующую навигацию для своего приложения со следующей настройкой :

  • AppContainer
    • Spla sh Экран
    • Экран настройки (Навигатор стека)
    • Главный экран (Навигатор стека)

Когда мое приложение запускается, оно переходит к экрану spla sh, который решает, запущен ли он впервые или нет, и в зависимости от этого решения вызывает this.props.navigation.navigate() на любом из главных экранов. или экран настройки.

Пока все это работает и является довольно стандартным.

Когда мое приложение запускается в первый раз, пользователь отправляется на экран настройки, где он перемещается по серии экранов, вводя данные и выбирая следующую кнопку, чтобы перейти к следующему экрану. Вот где проблема возникает. Мой первый экран просто содержит некоторый текст и следующую кнопку (которая является обычным компонентом кнопки), которая при нажатии вызывает this.props.navigation.push('nextviewname', {data: data}) для перехода к следующему представлению.

Следующее представление содержит ввод текста, а также назад и Следующие кнопки, где у меня проблемы. Когда я попадаю на этот экран после новой установки версии приложения на мой телефон Android X, ни один из входов не работает. Я не могу:

  • Нажмите следующий из спины
  • Нажмите стрелку назад в левом верхнем углу, которая является частью заголовка
  • Нажмите ввод текста ( курсор ненадолго появляется при вводе текста, но клавиатура не появляется)
  • Нажмите аппаратную клавишу возврата

В очень редких случаях некоторые из вышеперечисленных работают (например, ввод текста) иногда будет работать), а иногда я даже сделаю это на следующем шаге моей настройки, но редко, что я делаю все это через

Странно, все это работает, когда я отлаживаю свое приложение на своем телефоне .

Обновление: Я только что проверил на эмуляторе Android 9 и получаю ту же проблему.

Обновление 2: Это становится странным, когда приложение находится в нерабочем состоянии, я все равно могу вызвать меню реакции отладки, однако, когда я нажимаю Toggle Inspector, ничего не происходит (т.е. я не получаю интерфейс инспектора). Похоже, что это как-то ломает все.

Кто-нибудь видел / решил эту проблему раньше? На данный момент оно фактически сделало мое приложение бесполезным.

Обновление 3: Некоторый код, который, как мы надеемся, прояснит ситуацию:

const SetupUser = createStackNavigator(
  {
    SetupUser: WelcomeScreen,
    SetupName: UserName,
    SetupCurrentWeight: CurrentWeight,
    SetupGoalWeight: GoalWeight,
    SetupGoalDate: GoalDate,
    Summary: Summary,
    LogWeight: LogWeight,
  },
  {
    defaultNavigationOptions: {
      headerStyle: {
        backgroundColor: '#001830',
      },
      headerTintColor: '#fff',
      headerTitleStyle: {
        fontWeight: 'bold',
      },
    },
  },
);

const MainApp = createStackNavigator(
  {
    LogWeight: LogWeight,
    LogWeightSummary: LogWeightSummary,
  },
  {
    defaultNavigationOptions: {
      headerStyle: {
        backgroundColor: '#001830',
      },
      headerTintColor: '#fff',
      headerTitleStyle: {
        fontWeight: 'bold',
      },
    },
  },
);

export default createAppContainer(
  createSwitchNavigator(
    {
      MainApp: MainApp,
      SplashScreen: SplashScreen,
      SetupUser: SetupUser,
    },
    {
      initialRouteName: 'SplashScreen',
    },
  ),
);

При получении этого фрагмента кода (я Я удалил навигатор вкладок, так как ошибка все еще существует, даже без нее) Я думаю, что мне удалось отследить источник проблемы, но я все еще не уверен, как ее исправить. Первое загруженное представление - это экран spla sh, который выглядит следующим образом:

export default class SplashScreen extends React.Component {
constructor(props) {
    super(props);

    GoBinder.verifyDatabase()
      .then(GoBinder.getLastUser())
      .then(user => {
        this.props.navigation.navigate(
          user.user == null ? 'SetupUser' : 'MainApp',
        );
      })
      .catch(error => {
        GoBinder.toast('Error while checking initial user state: ' + error);
      });
  }
render() {
    return (
      <View style={styles.container}>
        <ActivityIndicator />
        <StatusBar barStyle="default" />
      </View>
    );
  }
}

В приведенном выше коде GoBinder.verifyDatabase () и GoBinder.getLastUser () являются вызовами собственного кода, который выполняет некоторую базу данных. Операция, чтобы настроить вещи и проверить, есть ли какие-либо существующие пользователи. Я полагаю, что проблема в том, что this.props.navigation.navigate срабатывает слишком быстро, из-за чего реактивная навигация загружает следующий экран, но в процессе запутывается.

Я пытался следовать рекомендациям в этом посте https://www.novemberfive.co/blog/react-performance-navigation-animations о перемещении кода блокировки в InteractionManager.runAfterInteractions в componentDidMount, однако это не имеет значения. Тем не менее, я вручную запускаю переход на новый экран с помощью кнопки, и все работает правильно, поэтому его действительно похоже на то, что процесс программно меняющихся экранов портит все.

Обновление 4: Выглядит как будто я немного подпрыгнул, он все еще довольно сильно зависает, перенося мой ответ в обновление:

Так что я не уверен, что это лучшее решение, но я нашел обходной путь. Сейчас я вызываю код своей базы данных в InteractionManager.runArfetInteraction(), как предложено в https://www.novemberfive.co/blog/react-performance-navigation-animations. Затем я вызываю setState с результатом функций БД для сохранения результата. Наконец, я использую обратный вызов на setState, чтобы вызвать фактическую навигацию. Мой полный рабочий код:

componentDidMount() {
    InteractionManager.runAfterInteractions(() => {
      GoBinder.verifyDatabase()
        .then(
          GoBinder.getLastUser().then(user => {
            this.setState(
              {
                user: user.user,
              },
              () => {
                this.props.navigation.navigate(
                  this.state.user == null ? 'SetupUser' : 'MainApp',
                );
              },
            );
          }),
        )
        .catch(error => {
          GoBinder.toast('Error while checking initial user state: ' + error);
        });
    });
  }

Спасибо за вашу помощь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...