react-native - 结合 React Navigation 3.0 和 JWT 根据身份验证状态确定 initialRouteName
问题描述
我正在尝试使与 JWT 客户端集成的普通 App.js 组件在集成 React Navigator 3.0 时正常运行
不幸的是,我只能做一个或另一个,而不是两者。我的问题是 React Navigator 有点劫持 App.js 并确定初始路线而不是通常的 App 组件渲染。
到目前为止,这是我的代码:
应用程序.js
import React, { Component } from 'react';
import { createAppContainer,
createBottomTabNavigator,
} from 'react-navigation';
import Auth from './src/screens/Auth';
import HomeScreen from './src/screens/HomeScreen';
class App extends Component {
constructor() {
super();
this.state = {
jwt: '',
};
}
render() {
if (!this.state.jwt) {
return (
<Auth />
);
} else if (this.state.jwt) {
return (
<HomeScreen />
);
}
}
}
const TabNavigator = createBottomTabNavigator({
Home: { screen: HomeScreen,
navigationOptions: {
tabBarLabel: 'Home',
}
},
Auth: { screen: Auth,
navigationOptions: {
tabBarLabel: 'Auth',
}
},
},
{ initialRouteName: App.state.jwt ? 'Home' : 'Auth' }
);
export default createAppContainer(TabNavigator);
如您所见,我的问题在于这一行:
{ initialRouteName: App.state.jwt ? 'Home' : 'Auth' }
如何在 TabNavigator 组件中获取 JWT 状态,以便定义正确的 initialRouteName?
this.state.jwt
App.state.jwt
显然不起作用,我尝试(但失败)将状态作为道具传递给 TabNavigator 对象。
任何帮助表示赞赏。
解决方案
这是正确的方法:
首先,您设置获取 Auth 令牌并将其状态保存在 App.js 中。然后将状态传递screenProps
给 Navigation 对象:
export default class App extends React.Component {
constructor() {
super();
this.state = {
jwt: '',
loading: true
};
this.newJWT = this.newJWT.bind(this);
this.deleteJWT = deviceStorage.deleteJWT.bind(this);
this.loadJWT = deviceStorage.loadJWT.bind(this);
this.loadJWT();
}
state = {
isLoadingComplete: false,
};
newJWT(jwt) {
this.setState({
jwt: jwt
});
}
render() {
if (this.state.loading) {
return (
<Loading size={'large'} />
);
} else if (!this.state.jwt) {
return (
<View style={styles.container}>
{Platform.OS === 'ios' && <StatusBar barStyle="default" />}
<TabNavigator screenProps={{setToken: this.newJWT }} />
</View>
);
}
导航对象将其传递给需要它的屏幕。
const TabNavigator = createMaterialTopTabNavigator(
{
Profile: {
screen: props => <ProfileScreen {...props.screenProps} />,
navigationOptions: {
//tabBarLabel: 'Perfil',
title: 'Header Title',
tabBarIcon: ({ tintColor, focused }) => (
<Ionicons
name={focused ? 'ios-person' : 'ios-person'} //TODO change to focused icon
size={26}
style={{ color: tintColor }}
/>
),
}
},
您可以看到道具可以作为 ScreenProps 传递,然后像这样读入子组件(屏幕):
export default class ProfileScreen extends React.Component {
constructor(props) {
super(props);
this.state = {
loading: true,
email: '',
username: '',
phone: '',
password: '',
name: '',
error: ''
};
}
componentDidMount() {
const headers = {
Authorization: this.props.jwt
};
api.get('/user')
.then((response) => {
this.setState({
email: response.data.data.attributes.email,
phone: response.data.data.attributes.phone,
username: response.data.data.attributes.username,
name: response.data.data.attributes.name,
loading: false
});
}).catch((error) => {
this.setState({
error: 'Error retrieving data',
loading: false
});
});
}
我想使用 Redux 会简单得多,但我仍在学习。
推荐阅读
- javascript - 如何避免事件监听器共享范围
- flutter - 如何知道一个文件真的存在于flutter-web中
- html - vue组件和tabindex,你是怎么做的?
- python - OSError:不允许操作 os.setegid
- python - 如何使用 sqlalchemy 从 Flask 中的 SQlite 数据库中获取(检索)数据
- java - 切换while循环
- react-native - React Native:将参数传递给 Drawer.Navigator
- ios - 如何从字典中检索 Firestore 数据并填充 Tableview 行/部分?
- javascript - 默认侧边栏收起
- mysql - 查询选择多个表