我正在尝试使与JWT客户端集成的普通App.js组件在集成React Navigator 3.0时能够正确运行
不幸的是,我只能使一个工作或另一个工作,而不能两者兼而有之。我的问题是,React Navigator会劫持App.js,并确定初始路径,而不是通常的App组件渲染。
到目前为止,这是我的代码:
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对象。
感谢您的帮助。
答案 0 :(得分:1)
这是正确的方法:
首先,您设置获取Auth令牌并将其状态保存在App.js中。然后,将状态screenProps
传递给导航对象:
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会更简单,但是我仍在学习。
答案 1 :(得分:0)
请问您是否包括登录屏幕以进行身份验证?