createSwitchNavigator 在 react-navigation 5.x 中的位置,用于从 react-navigation 4 迁移到 5.x
Where is placed createSwitchNavigator in react-navigation 5.x for migrating from react-navigation 4 to 5.x
我正在将 React Native 应用程序从 react-navigation 4 迁移到 5.x,但我找不到哪个包包含 createSwitchNavigation。具体来说,我对授权令牌检查部分有疑问。
使用 react-navigation 4 我有:
const switchNavigator = createSwitchNavigator({
ResolveAuth: ResolveAuthScreen,
signinFlow: createStackNavigator({
Signup: SignupScreen,
Signin: SigninScreen,
}),
appFlow: createBottomTabNavigator({
TrackCreate: TrackCreateScreen,
trackListFlow: createStackNavigator({
TrackList: TrackListScreen,
TrackDetail: TrackDetailScreen
}),
Account: AccountScreen,
})
}, {
initialRouteName: 'ResolveAuth'
});
然后我有一个包含 ResolveAuthScreen 组件的文件。
import React, { useEffect } from 'react';
import { connect } from 'react-redux';
const ResolveAuthScreen = (props) => {
useEffect(() => {
if (!props.token) {
props.navigation.navigate('loginFlow');
} else {
props.navigation.navigate('TrackList');
}
}, []);
return null;
};
const mapStateToProps = (state) => {
return {
token: state.auth.token,
};
};
export default connect(mapStateToProps, null)(ResolveAuthScreen);
其余的组件对于这个疑问并不重要。我想知道如何复制相同的 Switch 导航流程。
我想知道如何创建这样的东西:
const Switch = createSwitchNavigator();
export default function App() {
return (
<NavigationContainer>
<Switch.Navigator>
<Switch.Screen name="ResolveAuth" component={ResolveAuthScreen} />
<Switch.Screen name="signinFlow" component={SignInFlowScreens} />
<Switch.Screen name="appFlow" component={AppFlowScreens} />
</Switch.Navigator>
</NavigationContainer>
);
}
In earlier versions of React Navigation, there were 2 ways to handle this:
- Keep multiple navigators and use switch navigator to switch the active navigator to a different one upon login (recommended)
- Reset the state of the navigator to the desired screens upon login
但是对于 v5,您需要使用上下文。看看here看详细的例子!
v5 上没有切换导航器。你可以试试下面的代码
function App({ token }) {
const [isLoggedIn, setLoggedIn] = useState(false);
useEffect(() => {
setLoggedIn(!!token);
}, [token]);
return (
<NavigationContainer>
{isLoggedIn ? <AppFlowScreens /> : <SignInFlowScreens /> }
</NavigationContainer>
);
}
const mapStateToProps = (state) => {
return {
token: state.auth.token,
};
};
export default connect(mapStateToProps, null)(App);
为了使迁移更容易,您仍然可以使用@react-navigation/compat
中的createSwitchNavigator
按照官方文档(https://reactnavigation.org/docs/auth-flow/)进行操作,终于成功了。
关键部分是用于检查用户是否登录的变量必须是全局变量(可从任何屏幕访问)。就我而言,我使用了 Redux。
这是 App 导航的主要代码,我首先检查是否有来自 AsyncStorage 的令牌,然后转到 tabBar 屏幕(Home、Profile...)或登录屏幕:
import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { setToken } from '../store/actions/user';
import AsyncStorage from '@react-native-community/async-storage';
...
const appNavigator = () => {
const dispatch = useDispatch();
const user = useSelector(state => state.user);
useEffect(() => {
const getToken = async () => dispatch(setToken(await AsyncStorage.getItem('token')));
getToken();
}, [])
return (
<NavigationContainer>
{(user.token == null)
? <LoginStackScreen />
: <AppTabScreens />
}
</NavigationContainer>
)
};
在这种情况下,我在 redux 变量 中管理令牌的状态。因此,在登录屏幕中,我们不需要使用任何导航,例如“navigation.navigate('Home')”。我们只需要在用户登录并生成新令牌后更新 redux 变量:
//props.navigation.navigate('Home');
dispatch(setToken(newToken));
这将自动转到主屏幕,无需任何其他导航。
对于注销,我们只需将此 redux 变量设置为 null(同样,无需使用 navigation.navigate):
await AsyncStorage.clear();
//props.navigation.navigate('Auth');
dispatch(setToken(null));
我正在将 React Native 应用程序从 react-navigation 4 迁移到 5.x,但我找不到哪个包包含 createSwitchNavigation。具体来说,我对授权令牌检查部分有疑问。
使用 react-navigation 4 我有:
const switchNavigator = createSwitchNavigator({
ResolveAuth: ResolveAuthScreen,
signinFlow: createStackNavigator({
Signup: SignupScreen,
Signin: SigninScreen,
}),
appFlow: createBottomTabNavigator({
TrackCreate: TrackCreateScreen,
trackListFlow: createStackNavigator({
TrackList: TrackListScreen,
TrackDetail: TrackDetailScreen
}),
Account: AccountScreen,
})
}, {
initialRouteName: 'ResolveAuth'
});
然后我有一个包含 ResolveAuthScreen 组件的文件。
import React, { useEffect } from 'react';
import { connect } from 'react-redux';
const ResolveAuthScreen = (props) => {
useEffect(() => {
if (!props.token) {
props.navigation.navigate('loginFlow');
} else {
props.navigation.navigate('TrackList');
}
}, []);
return null;
};
const mapStateToProps = (state) => {
return {
token: state.auth.token,
};
};
export default connect(mapStateToProps, null)(ResolveAuthScreen);
其余的组件对于这个疑问并不重要。我想知道如何复制相同的 Switch 导航流程。 我想知道如何创建这样的东西:
const Switch = createSwitchNavigator();
export default function App() {
return (
<NavigationContainer>
<Switch.Navigator>
<Switch.Screen name="ResolveAuth" component={ResolveAuthScreen} />
<Switch.Screen name="signinFlow" component={SignInFlowScreens} />
<Switch.Screen name="appFlow" component={AppFlowScreens} />
</Switch.Navigator>
</NavigationContainer>
);
}
In earlier versions of React Navigation, there were 2 ways to handle this:
- Keep multiple navigators and use switch navigator to switch the active navigator to a different one upon login (recommended)
- Reset the state of the navigator to the desired screens upon login
但是对于 v5,您需要使用上下文。看看here看详细的例子!
v5 上没有切换导航器。你可以试试下面的代码
function App({ token }) {
const [isLoggedIn, setLoggedIn] = useState(false);
useEffect(() => {
setLoggedIn(!!token);
}, [token]);
return (
<NavigationContainer>
{isLoggedIn ? <AppFlowScreens /> : <SignInFlowScreens /> }
</NavigationContainer>
);
}
const mapStateToProps = (state) => {
return {
token: state.auth.token,
};
};
export default connect(mapStateToProps, null)(App);
为了使迁移更容易,您仍然可以使用@react-navigation/compat
createSwitchNavigator
按照官方文档(https://reactnavigation.org/docs/auth-flow/)进行操作,终于成功了。
关键部分是用于检查用户是否登录的变量必须是全局变量(可从任何屏幕访问)。就我而言,我使用了 Redux。
这是 App 导航的主要代码,我首先检查是否有来自 AsyncStorage 的令牌,然后转到 tabBar 屏幕(Home、Profile...)或登录屏幕:
import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { setToken } from '../store/actions/user';
import AsyncStorage from '@react-native-community/async-storage';
...
const appNavigator = () => {
const dispatch = useDispatch();
const user = useSelector(state => state.user);
useEffect(() => {
const getToken = async () => dispatch(setToken(await AsyncStorage.getItem('token')));
getToken();
}, [])
return (
<NavigationContainer>
{(user.token == null)
? <LoginStackScreen />
: <AppTabScreens />
}
</NavigationContainer>
)
};
在这种情况下,我在 redux 变量
//props.navigation.navigate('Home');
dispatch(setToken(newToken));
这将自动转到主屏幕,无需任何其他导航。
对于注销,我们只需将此 redux 变量设置为 null(同样,无需使用 navigation.navigate):
await AsyncStorage.clear();
//props.navigation.navigate('Auth');
dispatch(setToken(null));