使用 MST 的 React Navigation 5 身份验证流程,而不是 "switching"

React Navigation 5 authentication flow with MST, not "switching"

所以,我刚刚升级了一个 ignite-bowser project to their 5.0 template, which includes React Navigation 5, which requires a change from the legacy recommended method of using a SwitchNavigator to swap between 'Auth' and 'App' StackNavigators, to a new declarative auth flow approach,使 SwitchNavigator 变得多余。

仅供参考,Ignite Bowser 项目本质上是

支持的 React Native 模板应用程序
React Native
React Navigation
MobX State Tree
TypeScript
Reactotron
And more!

所以这一切看起来很简单,但是当使用存储在其中一个应用程序商店中的布尔值并在其中调用的操作中设置为 true 时,我无法让实际的导航器切换认证方法。

根据服务器日志和 Reactotron 提要,身份验证工作正常。之后重新加载应用程序确实会呈现应用程序导航器,但会话实际上无效,因为内存已被清除。所有后续请求均失败,但应用程序未切换到 Auth 导航器。

以下是相关的代码片段:

root-navigator.tsx

const RootStack = () => {
  const { pbidStore } = useStores()

  return (
    <Stack.Navigator
      screenOptions={{
        headerShown: false,
        gestureEnabled: true,
        stackPresentation: "modal",
      }}
    >
      {pbidStore.isAuthenticated ? (
        <Stack.Screen
          name="pbidStack"
          component={PbidNavigator}
          options={{
            headerShown: false,
          }}
        />
      ) : (
        <Stack.Screen
          name="authStack"
          component={AuthNavigator}
          options={{
            headerShown: false,
          }}
        />
      )}

    </Stack.Navigator>
/**
 * PbidStore Model
 */
 export const PbidStoreModel = types.model("PbidStore").props({
   ....

   isAuthenticated: types.optional(types.boolean, false),
 })
 .actions(self => ({
   setStatus(value?:  "idle" | "pending" | "done" | "error") {
     self.status = value
   },
   setAuthToken(token: string) {
     self.environment.pbidApi.setAuthToken(token)
   },
   setAuthenticated(value: boolean) {
     self.isAuthenticated = value
   },
   ...
 }))
 .actions(self => ({
   authenticate: flow(function*(email: string, password: string, remember: boolean) {
     self.setStatus("pending")
     try {
       const result = yield self.environment.pbidApi.authenticate(email, password)
       if (result.kind === "ok") {
         self.setAuthToken(result.token)
         self.setStatus("done")
         self.setAuthenticated(true)
         self.loadUser()
         if(remember)
           yield self.storeCredentials(email, password)
       } else {
         self.setStatus("error")
         self.setAuthenticated(false)
       }
     } catch {
       self.setStatus("error")
       self.setAuthenticated(false)
     }
   }),
...

在我写完这个问题并开始选择 SO 标签之后,不得不决定使用 mobx-react 还是 mobx-react-lite 或两者兼而有之,我想起了我 运行 遇到的问题在我经历的最后一次升级期间,在这两者之间切换,并使用 injectobserver

所以我意识到也许我的导航器需要被观察到...

导入 mobx-react-lite 并在下面包装 RootStack 为我解决了所有问题。

const RootStack = observer(() => {

希望这有助于让其他人免于头痛。

总而言之,我很高兴最近对 react-native 使用 Hooks 和 FunctionalComponents 所做的所有这些更改,以及它对关联库和最终我的代码库所做的更改,但是 wooof必须不断学习新的 API 并在我的项目完成之前重新建立项目基础是不是很累人!