首页 > 解决方案 > 退出 React Native 应用程序的最佳实践?

问题描述

我目前已经在我的应用程序上实现了注销功能(使用 firebase 身份验证):

const handleSignOut = () => {
  signOut(auth)
    .then(() => navigation.navigate("Login"))
    .catch((err) => console.error(err));
};

但是,我知道这还不够,因为我注意到某些状态正在跨用户保留(即使在注销后仍保留状态),我想知道清除/重置所有状态的最佳方法是什么。

我是否需要手动卸载所有组件(我仍然不太了解组件卸载的方式/时间),还是有一种简单的方法可以使用导航或上下文工具来实现这一点?

我正在使用 Context API 和 React Navigation:

const Stack = createStackNavigator();

const Navigation = () => {
  return (
    <NavigationContainer>
      <Stack.Navigator
        headerMode="none"
      >
        <Stack.Screen
          name="Register"
          component={RegisterScreen}
        />
        <Stack.Screen
          name="Login"
          component={LoginScreen}
        />
        <Stack.Screen
          name="Home"
          component={HomeScreen}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
};

标签: react-nativereact-navigationreact-context

解决方案


很难说,因为其中很多都是特定于应用程序的,但一般来说,您需要专用一个能够破坏用户会话的方法,并确保它是持久的。也许它正在退出 Firebase,也许它正在清除一些 cookie,也许它正在更新一些其他持久状态。

关键是,您编写了一个方法来负责执行所有数据操作,以确保会话不再存在。重要的是,它与任何导航或其他内容无关。这只是纯粹的数据操作。

然后你有这个可重用的功能来注销可以从任何地方调用的用户。应用于您的示例...

// Notice that things that can possibly fail are wrapped in dedicated try/catches.
// You don't want the failure to clear some state prevent your ability to clear others.
const doSomeBigGlobalSessionLogout = async () => {
  const maybeErrors = [];
  try {
    await firebase.signOut(auth);
  } catch (e) {
    maybeErrors.push(e);
  }
  try {
    await clearSomeOtherPersistentState();
  } catch (e) {
    maybeErrors.push(e);
  }

  /* do something with errors */
  // for (error of maybeErrors) { ... }

  // Still resolve successfully, because you won't want to lock the user from
  // not being able to sign out.
  return Promise.resolve();
};

// Here you can trust it will never lock the user out, and will always clear state as best as it can.
doSomeBigGlobalSessionLogout()
   // You *will* get here.
  .then(() => navigation.navigate("Login"));

最后,在 UI 方面,首先移动用户可能是有意义的。否则用户会看到他们的状态从他们眼前的屏幕上消失!

Promise.resolve()
  .then(() => navigation.navigate("SomePlaceThatsPretty"));
  .then(doSomeBigGlobalSessionLogout)
  .then(() => navigation.navigate("Login"));

推荐阅读