使用具有Redux和Firebase身份验证的React-Navigation v5

时间:2020-04-20 06:19:44

标签: react-native redux firebase-authentication react-navigation react-navigation-v5

我正在尝试使用 React-Navigation版本5 (不是Ver 4)在用户登录时从身份验证屏幕/堆栈切换到非身份验证屏幕/堆栈。一个简单的示例在文档中已得到充分证明。

但是,文档没有提供有关使用 Redux Google Firebase身份验证的详细信息。成功登录后,我收到以下警告消息。

Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.

我认为此警告消息的原因是,对Redux动作(动作创建者)的调用导致重新呈现身份验证屏幕,而导航代码已经卸载了该屏幕! 卸载身份验证屏幕后,如何更新Redux的商店?

导航代码:

...
// If user is logged in -> display the app/main stack
if (props.loggedIn) 
{
    const MyTabs = createBottomTabNavigator();
    return (
        <NavigationContainer>
            <MyTabs.Navigator initialRouteName="UserTypeScreen">
                <MyTabs.Screen name="UserTypeScreen" component={UserTypeScreen}  />
                <MyTabs.Screen name="PermissionsScreen" component={PermissionsScreen} />
            </MyTabs.Navigator>
        </NavigationContainer>
    ); 
}
// If user is NOT logged in -> display the auth stack
else {
    const AuthStack = createStackNavigator();
    return (
        <NavigationContainer>
            <AuthStack.Navigator>
                <AuthStack.Screen name="AuthScreen" component={AuthScreen} />
                <AuthStack.Screen name="AuthLinkScreen" component={AuthLinkScreen} />
            </AuthStack.Navigator>
        </NavigationContainer>
    ); 
}
...

身份验证屏幕:

...
useEffect( () => {
    const unSubscribe = firebase.auth().onAuthStateChanged( (user) => {
        if (user) {
            const idToken = firebase.auth().currentUser.getIdToken(); 
            const credential = firebase.auth.PhoneAuthProvider.credential(idToken); 

            // The following statement causes a warning message, because it causes re-rendering of an unmounted screen
            props.acLoginUserSuccess(user, credential); 
        } 
    }); 

    return () => {
        unSubscribe();
    };
}, []); 
...

Redux Action Creator:

...
export const acLoginUserSuccess = (user, credential) => {
    return {
        type: LOGIN_USER_SUCCESS,
        payload: { user: user, credential: credential }
  };
};
...

2 个答案:

答案 0 :(得分:0)

我很快就遍历了您的代码,但这就是我的想法(可能是错误的)。

文档建议在已安装的屏幕上获取令牌(示例中为App.js)。

如果useEffect挂钩中的firebase.auth()侦听器位于App.js中,则不会有问题。

我认为显示警告消息是因为当您在MyTabs路线中时,未安装AuthScreen。

将侦听器移动到App.js或与auth和MyTabs屏幕位于同一堆栈的屏幕上将解决我认为的问题。

答案 1 :(得分:0)

我相信下面的代码写的是获得令牌并存储在Redux商店中的想法。

是否可以在凭据验证成功后移动此逻辑,而不是 卸载?

请提供有效的理由,使这种逻辑变得不正确,以便更好地评估问题

firebase.auth().onAuthStateChanged( (user) => {
    if (user) {
        const idToken = firebase.auth().currentUser.getIdToken(); 
        const credential = firebase.auth.PhoneAuthProvider.credential(idToken); 

        // The following statement causes a warning message, because it causes re-rendering of an unmounted screen
        props.acLoginUserSuccess(user, credential); 
    } 
});