AWS Amplify Auth / реагировать на навигацию: как получить доступ к состоянию аутентификации? - PullRequest
1 голос
/ 05 мая 2019

В моем React Native мобильном приложении я хотел бы аутентифицировать своих пользователей с помощью AWS Amplify Authentication и управлять навигацией между экранами с помощью React Navigation . Я пытался реализовать все «по книге», то есть согласно документам и моему приложению концептуально выглядит так:

// import statements skipped

class FirstTabScreen extends React.Component {
  render = () => {
    {/* access some data passed in screenProps */}
    const someData = this.props.screenProps.someData;
    {/* TODO: how to access AWS Amplify auth data here ?!? */}
    {/* this.props contains screenProps and navigation objects */}
    console.log("this.props: ", this.props);
    {/* this.props.authState is undefined */}
    console.log("this.props.authState: ", this.props.authState);
    return <View><Text>First Tab - some data: {someData}</Text></View>
  };
}

class SecondTabScreen extends React.Component {
  render = () => {
    const otherData = this.props.screenProps.otherData;
    return <View><Text>Second Tab - other data: {otherData}</Text></View>
  };
}

const AppNavigator = createBottomTabNavigator({
  FirstTab: { screen: FirstTabScreen },
  SecondTab: { screen: SecondTabScreen },
});

const AppContainer = createAppContainer(AppNavigator);

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      someData: null,
      otherData: null,
    };
  }

  componentDidMount = () => {
    this.setState({ someData: 'some data', otherData: 'other data' });
  };

  render = () => {
    return (
      <Authenticator>
        <AppContainer
          screenProps={{
            someData: this.state.someData,
            otherData: this.state.otherData,
          }}
        />
      </Authenticator>
    );
  };
}

export default App;

Пример кода выше пропускает несколько важных деталей; Я создал полную Экспо Снэк .

AWS Amplify Authenticator оборачивает приложение и делает данные аутентификации доступными для встроенных компонентов, например, например. this.props.authState; см документы .

Моя проблема Теперь я не понимаю, как получить доступ к этим данным аутентификации, например, в. FirstTabScreen: В этом компоненте this.props содержит screenProps и navigation объектов, но this.props.authState равно undefined. С AppContainer и AppNavigator между Authenticator и, например, FirstTabScreen, я не вижу, как передавать данные аутентификации в качестве реквизита или транспортировать их каким-либо другим способом.

Кроме того , я просто передаю все данные всем встроенным компонентам в screenProps; это работает, но не все экраны требуют всех данных. Как мне передать им только те данные, которые им действительно нужны? Я знаю о передаче параметров в маршруты , но все примеры кода там имеют Button и используют this.props.navigation.navigate(...) в обработчике onPress. У меня нет кнопок на этих экранах, и они мне не нужны - в конце концов, переход на другую вкладку - это то, для чего нужны вкладки на панели навигации нижней вкладки?!?

Может ли кто-нибудь пролить свет на это для меня?

Ответы [ 2 ]

1 голос
/ 11 мая 2019

с использованием screeProp - не рекомендуется react navigation v3

Я полагаю, что больше не рекомендуется помещать навигацию, например TabNavigator, в компонент. Я не совсем уверен, как правильно обрабатывать такие случаи в V3. Недавно я захотел перейти с V1 на V3 и разочаровался в обновлении, так как не мог найти достаточно информации о том, что делать с моими вложенными навигаторами.

другая идея от esipavicius

не переносить экраны в навигатор стека, в который входит навигатор с вкладками. Может быть, вы можете использовать navigationAction setState или setParams с клавишами params и navigator. Когда вы можете dispatch это. И автоматически изменяет состояние с помощью параметров, на которые вы отправили scren.

ВАРИАНТ 1 - ИСПОЛЬЗОВАНИЕ ЭКРАНА PROP

Ваш выбор пропуская экранные реквизиты

class App extends React.Component {

  componentDidMount = () => {
    this.setState({ someData: 'some data', otherData: 'other data' });
  };

  render = () => {
    return (
      <Authenticator>
        <AppContainer
          screenProps={{ myProp: "test" }}
        />
      </Authenticator>
    );
  };
}

ВАРИАНТ 2 - ИСПОЛЬЗОВАНИЕ API РЕАКТИВНОГО КОНТЕКСТА

Использование API-интерфейса Context и его обертывание вокруг <AppContainer>.

class App extends React.Component {
  render = () => {
    return (
      <FormContext.Provider value={this.state}>
        <AppContainer />
      </FormContext.Provider>
    );
  };
}

Затем потребляйте его на каждом из ваших экранов.

class FirstTabScreen extends React.Component {
  render(){
    return(
      <FormContext.Consumer>
        { (context) => ( 
             // your logic 
        )}
      </FormContext.Consumer>
  };
}

Вариант 3 - TAB NAVIGATOR OBJECT

Вы можете передать TabNavigatorObject

createBottomTabNavigator(RouteConfigs, BottomTabNavigatorConfig);

Вы можете передать дополнительную опцию BottomTabNavigator в BottomTabNavigatorConfig.

const BottomTabNavigator = StackNavigator(routesConfig, BottomTabNavigatorConfig)

BottomTabNavigatorConfig - это опция, и вы можете проверить api docs

{ initialRouteName: 'Home', navigationOptions: .... }

Вариант 4 - ПОЛУЧИТЬ ПАРАМ ОТ РОДИТЕЛЯ

как объяснено на github и в api docs , вы можете получить родительский компонент и затем использовать getParam.

const parent = navigation.dangerouslyGetParent();
const yourParam = parent.getParam('yourParamName', 'default value')

Вы можете найти много дискуссий о прохождении реквизита с помощью навигатора вкладок на github

0 голосов
/ 08 мая 2019

1) Я бы предложил не использовать никакой подобной логики вне этого навигатора.Если вы хотите войти в систему, сделайте что-то вроде:

const rootStack = createSwitchNavigator({
    Login: { screen: LoginNavigator },
    Main: createBottomTabNavigator({
        FirstTab: { screen: FirstTabScreen },
        SecondTab: { screen: SecondTabScreen },
    });
})

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

2) Используйте любой магазин для приложения.Например, react-navigation прекрасно работает с redux.Вы можете сохранить всю информацию там.Старайтесь не использовать screenProps для простых случаев, подобных этому.Также вам не нужно отправлять authState на другие экраны, просто сохраните их в магазине.

3) Как только вы захотите выйти из системы.Выполните: Auth.signOut(), очистите магазин и перейдите к экрану входа.

Попробуйте выполнить эти простые шаги, и вы сможете реализовать гораздо более сложные вещи

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