reactjs - 反应本机中的redux auth状态问题
问题描述
我正在使用 react native 和 redux 并且性能很慢。例如,在初始页面上,我有一个检查系统,如果处于我的 redux 状态的用户已通过身份验证,则如果不显示身份验证屏幕,则显示主页。
当我的用户通过身份验证时,我的应用程序最初会渲染身份验证屏幕几秒钟,然后渲染主屏幕,这是一个糟糕的用户体验,所以可能我的 redux 状态需要时间来更新并且速度很慢。
请查看我的代码并帮助我解决我做错的事情。
我正在 AsyncStorage 中检查经过身份验证的令牌以确定经过身份验证的用户。
导航.js
const Root = (props) => {
useEffect(() => {
const bootstrapAsync = async () => {
let token;
// token = null;
try {
token = await AsyncStorage.getItem('FBIdToken');
} catch (e) {
console.log(e);
}
if(token !== null){
const decodedToken = jwtDecode(token);
if(decodedToken.exp * 1000 < Date.now()) {
store.dispatch(logoutUser());
} else {
store.dispatch({ type: SET_AUTHENTICATED });
store.dispatch(getUserData());
}
}
};
bootstrapAsync();
setIsLoading(false);
}, []);
return (
<NavigationContainer ref={navigationRef}>
{
!props.user.authenticated ? (
<AuthStackScreen />
) : (
<DrawerScreen />
)
}
</NavigationContainer>
)
};
const mapStateToProps = (state) => ({
user: state.user,
UI: state.UI
});
export default connect(mapStateToProps)(Root);
减速器.js
import { SET_USER, SET_AUTHENTICATED, SET_UNAUTHENTICATED } from '../types';
const initialState = {
authenticated: false,
loading: false,
credentials: {},
likes: [],
notifications: []
};
export default function(state = initialState, action){
switch(action.type){
case SET_AUTHENTICATED:
return {
...state,
authenticated: true
};
case SET_UNAUTHENTICATED:
return initialState;
case SET_USER:
return {
authenticated: true,
loading: false,
...action.payload
};
default:
return state;
}
}
解决方案
你有多种选择
- 显示加载屏幕
- 把表达式转过来
- 默认已验证为 true
我喜欢的解决方案(我已经多次这样做了):
- 创建一个名为 StartupScreen 的自己的屏幕
- 在那里做所有与登录相关的事情
- 在那里显示一个 ActivityIndicator
我的例子:
const StartupScreen = () => {
const dispatch = useDispatch()
useEffect(() => {
const tryLogin = async () => {
const userData = await AsyncStorage.getItem(USER_DATA)
if (!userData) {
dispatch(setDidTryAL())
return
}
const parsedUserData = JSON.parse(userData)
const {user_id, access_token, expires_at} = parsedUserData
const expirationDate = new Date(expires_at * 1000)
if (expirationDate <= new Date() || !access_token | !user_id) {
dispatch(setDidTryAL())
return
}
const userDetails = JSON.parse(await AsyncStorage.getItem(USER_DETAILS))
dispatch({type: AUTHENTICATE, user_id, access_token, expires_at, userDetails})
}
tryLogin()
}, [dispatch])
return (
<View style={styles.screen}>
<ActivityIndicator size='large' color={Colors.primary}/>
</View>
)
}
export default StartupScreen
还有我的根导航器(现代的做法):
const AppNavigator = () => {
const isAuthenticated = useSelector(state => !!state.auth.access_token)
const didTryAutoLogin = useSelector(state => state.auth.didTryAutoLogin)
return (
<SafeAreaProvider>
<NavigationContainer>
{ !isAuthenticated && didTryAutoLogin && <LoginAndRegisterNavigator/> }
{ !isAuthenticated && !didTryAutoLogin && <StartupScreen/>}
</NavigationContainer>
</SafeAreaProvider>
)
}
export default AppNavigator
对我来说,我什至看不到加载屏幕,因为登录过程工作得太快了。此外,屏幕应该与用户稍后能够看到的背景颜色相同。他甚至不会注意到装载的东西。
推荐阅读
- spring-boot - 消息处理时出现 Kafka 错误
- c# - 类和命名空间的引用 Visual Studio 2017
- c - 如何评估 x?y:a?b:c?
- python - 将 datetime 转换为最近的时间点
- c# - 如何在 xamarin.forms 中读取图像源或图像名称?
- android - 单个活动或多个活动中的多个布局?
- php - 根据简码(路径)参数从对象中提取数据
- maven - 在 maven pom.xml 文件中出现错误“Missing artifact com.beust:jcommander:jar:1.66”。有什么建议可以解决这个问题吗?
- android - 将自定义 Android 活动/视图链接到 React Native
- grafana - 如何将 grafana 查询的精度更改为 influxdb?