AWS Amplify Auth / react-navigation:如何访问授权状态?
AWS Amplify Auth / react-navigation: How to access auth state?
在我的React Native mobile application, I would like to authenticate my users using AWS Amplify Authentication and manage navigation between screens using React Navigation。我尝试实现所有内容 "by the book",即根据文档和我的应用程序 概念上 看起来像这样:
// 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;
上面的代码示例跳过了一些重要的细节;我创建了一个完整的 Expo Snack.
AWS Amplify Authenticator
包装应用程序并使身份验证数据可供嵌入式组件使用,例如this.props.authState
;参见 docs。
我的问题现在是我不明白如何访问这个授权数据,例如FirstTabScreen
:在该组件中,this.props
包含 screenProps
和 navigation
对象,但 this.props.authState
是 undefined
。 AppContainer
和 AppNavigator
在 Authenticator
之间,例如FirstTabScreen
,我不知道如何将身份验证数据作为 props 传递或通过其他方式传输它们。
此外,我只是将所有数据传递给screenProps
中的所有嵌入式组件;这确实有效,但并非所有屏幕都需要所有数据。我将如何只向他们传递他们实际需要的数据?我知道 passing parameters to routes,但其中的所有代码示例都有一个 Button
并在 onPress
处理程序中使用 this.props.navigation.navigate(...)
。我在这些屏幕上没有任何按钮,也不需要任何按钮 - 毕竟,导航到不同的选项卡是底部选项卡导航栏中的选项卡的用途?!?
谁能帮我解释一下这个问题?
1) 我建议不要在导航器之外使用任何这样的逻辑。如果您想登录,请执行以下操作:
const rootStack = createSwitchNavigator({
Login: { screen: LoginNavigator },
Main: createBottomTabNavigator({
FirstTab: { screen: FirstTabScreen },
SecondTab: { screen: SecondTabScreen },
});
})
它将为您提供更多登录可能性,一旦您知道用户已登录,只需将他导航到主堆栈即可。
2) 为应用程序使用任何商店。例如 react-navigation
与 redux
配合得很好。您可以在那里保存所有信息。
对于这种简单的情况,尽量不要使用 screenProps
。另外你不需要发送 authState
到其他屏幕,只需保存到商店即可。
3) 一旦你想退出。执行:Auth.signOut()
,清理存储,然后导航至登录屏幕。
尝试遵循这些简单的步骤,您将能够实现更复杂的事情
使用 screeProp
是 not encouraged on react navigation v3
I believe it's no longer encouraged to put navigation such as TabNavigator nested within a component. I'm not quite sure how to handle such cases gracefully in V3. I wanted to upgrade from V1 to V3 recently and gave up on the upgrade since I couldn't find enough info on what to do with the nested navigators I have.
来自 esipavicius
的另一个想法
do not wrap screens to stack navigator which include the tab navigator. Maybe you Can use navigationAction
setState
or setParams
with params
and navigator
key. When You Can dispatch
it. And automaticaly changes state with params to which scren you dispatched.
选项 1 - 使用屏幕道具
你的选择
class App extends React.Component {
componentDidMount = () => {
this.setState({ someData: 'some data', otherData: 'other data' });
};
render = () => {
return (
<Authenticator>
<AppContainer
screenProps={{ myProp: "test" }}
/>
</Authenticator>
);
};
}
选项 2 - 使用 REACT 上下文 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);
您可以将额外的选项传递给 BottomTabNavigatorConfig
中的 BottomTabNavigator
。
const BottomTabNavigator = StackNavigator(routesConfig, BottomTabNavigatorConfig)
BottomTabNavigatorConfig 是一个选项,您可以检查 the api docs
{ initialRouteName: 'Home', navigationOptions: .... }
选项 4 - 从父项中检索参数
as explained on github and in 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
在我的React Native mobile application, I would like to authenticate my users using AWS Amplify Authentication and manage navigation between screens using React Navigation。我尝试实现所有内容 "by the book",即根据文档和我的应用程序 概念上 看起来像这样:
// 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;
上面的代码示例跳过了一些重要的细节;我创建了一个完整的 Expo Snack.
AWS Amplify Authenticator
包装应用程序并使身份验证数据可供嵌入式组件使用,例如this.props.authState
;参见 docs。
我的问题现在是我不明白如何访问这个授权数据,例如FirstTabScreen
:在该组件中,this.props
包含 screenProps
和 navigation
对象,但 this.props.authState
是 undefined
。 AppContainer
和 AppNavigator
在 Authenticator
之间,例如FirstTabScreen
,我不知道如何将身份验证数据作为 props 传递或通过其他方式传输它们。
此外,我只是将所有数据传递给screenProps
中的所有嵌入式组件;这确实有效,但并非所有屏幕都需要所有数据。我将如何只向他们传递他们实际需要的数据?我知道 passing parameters to routes,但其中的所有代码示例都有一个 Button
并在 onPress
处理程序中使用 this.props.navigation.navigate(...)
。我在这些屏幕上没有任何按钮,也不需要任何按钮 - 毕竟,导航到不同的选项卡是底部选项卡导航栏中的选项卡的用途?!?
谁能帮我解释一下这个问题?
1) 我建议不要在导航器之外使用任何这样的逻辑。如果您想登录,请执行以下操作:
const rootStack = createSwitchNavigator({
Login: { screen: LoginNavigator },
Main: createBottomTabNavigator({
FirstTab: { screen: FirstTabScreen },
SecondTab: { screen: SecondTabScreen },
});
})
它将为您提供更多登录可能性,一旦您知道用户已登录,只需将他导航到主堆栈即可。
2) 为应用程序使用任何商店。例如 react-navigation
与 redux
配合得很好。您可以在那里保存所有信息。
对于这种简单的情况,尽量不要使用 screenProps
。另外你不需要发送 authState
到其他屏幕,只需保存到商店即可。
3) 一旦你想退出。执行:Auth.signOut()
,清理存储,然后导航至登录屏幕。
尝试遵循这些简单的步骤,您将能够实现更复杂的事情
使用 screeProp
是 not encouraged on react navigation v3
I believe it's no longer encouraged to put navigation such as TabNavigator nested within a component. I'm not quite sure how to handle such cases gracefully in V3. I wanted to upgrade from V1 to V3 recently and gave up on the upgrade since I couldn't find enough info on what to do with the nested navigators I have.
来自 esipavicius
的另一个想法do not wrap screens to stack navigator which include the tab navigator. Maybe you Can use
navigationAction
setState
orsetParams
withparams
andnavigator
key. When You Candispatch
it. And automaticaly changes state with params to which scren you dispatched.
选项 1 - 使用屏幕道具
你的选择
class App extends React.Component {
componentDidMount = () => {
this.setState({ someData: 'some data', otherData: 'other data' });
};
render = () => {
return (
<Authenticator>
<AppContainer
screenProps={{ myProp: "test" }}
/>
</Authenticator>
);
};
}
选项 2 - 使用 REACT 上下文 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);
您可以将额外的选项传递给 BottomTabNavigatorConfig
中的 BottomTabNavigator
。
const BottomTabNavigator = StackNavigator(routesConfig, BottomTabNavigatorConfig)
BottomTabNavigatorConfig 是一个选项,您可以检查 the api docs
{ initialRouteName: 'Home', navigationOptions: .... }
选项 4 - 从父项中检索参数
as explained on github and in 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