AWS Amplify Auth / react-navigation:如何访问身份验证状态?

时间:2019-05-05 09:46:39

标签: react-native react-navigation aws-amplify

在我的React Native移动应用程序中,我想使用AWS Amplify Authentication对用户进行身份验证,并使用React Navigation管理屏幕之间的导航。我试图“按书”实施所有内容,即按照文档,并且我的应用从概念上说如下:

library("interplot")
interplot(m=m.glm.cl$glm_res, var1='wt', var2='disp', ci=.9, ralpha=.3, rfill='dodgerblue1') +
  geom_hline(yintercept=0, linetype="dashed") +
  guides(colour=guide_legend(override.aes=list(size=3)))

上面的代码示例跳过了一些重要的细节;我已经创建了完整的Expo Snack

AWS Amplify // 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; 包装应用程序,并向嵌入式组件提供身份验证数据,例如Authenticator;参见docs

我的问题,现在是我不了解如何访问该身份验证数据,例如this.props.authState:在该组件中,FirstTabScreen包含this.propsscreenProps对象,但是navigationthis.props.authStateundefinedAppContainer之间的AppNavigatorAuthenticator FirstTabScreen,我看不到如何将身份验证数据作为道具传递或通过其他方式传输。

此外,我只是将所有数据传递给screenProps中的所有嵌入式组件;确实可以,但是并非所有屏幕都需要所有数据。我将如何仅将它们实际需要的数据传递给他们?我知道passing parameters to routes,但是其中的所有代码示例都有一个Button,并在this.props.navigation.navigate(...)处理程序中使用onPress。我在这些屏幕上没有任何按钮,也不需要任何按钮-毕竟,导航至其他标签页是底部标签页导航栏中的标签页用于?!?

有人可以帮我一下吗?

2 个答案:

答案 0 :(得分:1)

使用screePropnot encouraged on react navigation v3

  

我认为,不再鼓励将诸如TabNavigator之类的导航嵌套在组件中。我不太确定如何在V3中正常处理此类情况。我最近想从V1升级到V3,并放弃了升级,因为我找不到足够的信息来处理嵌套导航器。

esipavicius的另一个想法

  

请勿将屏幕包装到包含选项卡导航器的堆栈导航器。也许可以通过navigationActionsetState键使用setParams paramsnavigator。何时可以dispatch。并通过您分配了scren的参数自动更改状态。

选项1-使用屏幕道具

您选择的passing screen props

class App extends React.Component {

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

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

选项2-使用REACT CONTEXT API

使用Context api并将其包装在<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导航器对象

您可以通过TabNavigatorObject

createBottomTabNavigator(RouteConfigs, BottomTabNavigatorConfig);

您可以向BottomTabNavigator中的BottomTabNavigatorConfig传递一个附加选项。

const BottomTabNavigator = StackNavigator(routesConfig, BottomTabNavigatorConfig)

BottomTabNavigatorConfig是一个选项,您可以检查the api docs

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

选项4-从父级检索参数

explained on github一样,在the api docs中,您可以检索父组件,然后使用getParam

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

您可以找到many discussion about passing props with tab navigator on github

答案 1 :(得分:0)

1)我建议不要在导航器外使用任何此类逻辑。如果要登录,请执行以下操作:

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

这将为您提供更多的登录可能性,一旦您知道用户已登录,只需将其导航到主堆栈即可。

2)使用任何商店作为应用程序。例如,react-navigationredux一起使用效果很好。您可以在那里保存所有信息。 对于这种简单情况,请尽量不要使用screenProps。另外,您无需将authState发送到其他屏幕,只需保存即可存储。

3)要注销。请执行:Auth.signOut(),清理存储,然后导航到“登录”屏幕。

尝试遵循这些简单的步骤,您将能够实现更复杂的事情