使用MOBX在Reaction本机中存储状态时,无法导航到不同的导航菜单 [英] unable to navigate to different navigation menu while using mobx for state storage in react native

查看:0
本文介绍了使用MOBX在Reaction本机中存储状态时,无法导航到不同的导航菜单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对Mobx还是个新手,一般来说,我的反应是原生的, 我正在尝试使用mobx在我的导航堆栈中实现状态值更改,这样当我的登录按钮被单击时,状态值的值就会更改,导航值参数内标识将更新为mobx存储中的最新值 但这不起作用

我收到错误消息:任何导航器都未处理有效负载为{";name";:";dashboard";}的操作‘导航’。 请就实时更改mobx存储数据的值和导航的最佳方式给我建议

我使用hoe DPO在导航中更改状态值后,使用useselector从存储区获取状态值

查看下面的登录屏幕代码

import React, { FC, useState } from "react"
import {
  View,
  ViewStyle,
  TextStyle,
  ImageStyle,
  SafeAreaView,
  TouchableOpacity,
  TextInput,
  ImageBackground,
  KeyboardAvoidingView,
  Platform,
} from "react-native"
import { StackScreenProps } from "@react-navigation/stack"
import { observer } from "mobx-react-lite"
import {
  Button,
  Header,
  Screen,
  Text,
  GradientBackground,
  AutoImage as Image,
} from "../../components"
import { color, spacing, typography } from "../../theme"
import { NavigatorParamList } from "../../navigators"
import { useTokenStore } from "../../utils/storage"


const wragbyLogo = require("./logo.png")
const ScreenBg = require("./bg.png")

const FULL: ViewStyle = { flex: 1 }
const CONTAINER: ViewStyle = {
  backgroundColor: color.transparent,
  paddingHorizontal: spacing[4],
}
const TEXT: TextStyle = {
  color: color.palette.white,
  fontFamily: typography.primary,
}
const BOLD: TextStyle = { fontWeight: "bold" }

const CONTAIN: TextStyle = {
  padding: 20,
  flex: 1,
}

const ALMOST: TextStyle = {
  ...TEXT,
  ...BOLD,
  fontSize: 26,
  fontStyle: "italic",
}

const HOME_LOGO: ImageStyle = {
  alignSelf: "center",
  marginVertical: spacing[5],
  maxWidth: "100%",
  marginTop: 100,
  width: 200,
  height: 60,
}
const CONTENT: TextStyle = {
  ...TEXT,
  color: "#BAB6C8",
  fontSize: 15,
  lineHeight: 22,
  marginBottom: spacing[5],
}

const TEXT_INPUT: TextStyle = {
  ...TEXT,
  backgroundColor: "#fff",
  marginTop: 10,
  marginLeft: 10,
  marginRight: 20,
  borderWidth: 2,
  borderColor: "lightblue",
  fontSize: 12,
  padding: 10,
  borderRadius: 8,
  height: 50,
  color: "#20162D",
  lineHeight: 22,
  marginBottom: spacing[1],
}
const TEXT_INPUT_END: TextStyle = {
  ...TEXT,
  backgroundColor: "#fff",
  marginTop: 10,
  marginLeft: 10,
  marginRight: 20,
  borderWidth: 2,
  borderColor: "lightblue",
  fontSize: 12,
  padding: 10,
  borderRadius: 8,
  height: 50,
  color: "#20162D",
  lineHeight: 22,
}
const CONTINUE: ViewStyle = {
  paddingVertical: spacing[4],
  paddingHorizontal: spacing[4],
  backgroundColor: "#051C5C",
}
const LOGO_TEXT: ViewStyle = {
  alignItems: "center",
  justifyContent: "center",
  paddingHorizontal: spacing[4],
  marginBottom: 100,
}
const CONTINUE_TEXT: TextStyle = {
  ...TEXT,
  ...BOLD,
  fontSize: 13,
  letterSpacing: 2,
}

const BLUE_TEXT: TextStyle = {
  ...TEXT,
  ...BOLD,
  color: "#00F",
}
const ACTION_LINK: TextStyle = {
  ...TEXT,
  ...BOLD,
  flexDirection: "row",
  marginTop: 25,
  alignItems: "center",
  justifyContent: "center",
  letterSpacing: 2,
}

const FOOTER_CONTENT: ViewStyle = {
  paddingVertical: spacing[4],
  paddingHorizontal: spacing[4],
}

const BOTTOM_HALF: ViewStyle = {
  flex: 1,
  padding: 30,
  borderWidth: 4,
  borderTopLeftRadius: 20,
  borderTopRightRadius: 20,
  borderColor: "#fff",
  backgroundColor: "#fff",
}
const LABEL: TextStyle = {
  marginTop: 30,
  color: "#000",
}
const NORMAL_TEXT: TextStyle = {
  color: "#000",
  marginTop: 5,
}
const RED_TEXT: TextStyle = {
  color: "#f00",
  textAlign: "right",
}
const RED_ACTION_LINK: TextStyle = {
  ...TEXT,
  ...BOLD,
  marginTop: 10,
  marginBottom: 10,
  marginRight: 20,
}
const SUBJECT: TextStyle = {
  fontWeight: "bold",
  color: "#000",
  fontSize: 20,
}
const KEYBOARD: TextStyle = {
  flex: 1,
}

export const LoginScreen: FC<StackScreenProps<NavigatorParamList, "login">> = observer(
  ({ navigation }) => {
    const { setToken } = useTokenStore(); 


    const showDashboard = () => {
     const newtokenBool =  setToken();
     console.log("newtokenBool >> "+ newtokenBool)

      navigation.navigate("dashboard")
    }
    const [loading, setLoading] = useState(false)
    const [email, setEmail] = useState("")
    const [password, setPassword] = useState("")
    // const [username, setUsername] = useState('mikeairtel@gmail.com');
    // const [password, setPassword] = useState('Password123');

    return (
      <ImageBackground source={ScreenBg} style={FULL}>
        <Image source={wragbyLogo} style={HOME_LOGO} />
        <View style={LOGO_TEXT}>
          <Text>powered by SAP...</Text>
        </View>
        <View style={BOTTOM_HALF}>
          <SafeAreaView>
                <Text style={SUBJECT}>Login</Text>
                <Text style={LABEL}>Email</Text>

                <TextInput
                  style={TEXT_INPUT}
                  placeholderTextColor="#D8D8D8"
                  onChangeText={(email) => setEmail(email)}
                  placeholder=""
                  autoCapitalize="none"
                  value={email}
                />
                <Text style={LABEL}>Password</Text>

                <TextInput
                  style={TEXT_INPUT_END}
                  placeholderTextColor="#D8D8D8"
                  onChangeText={(password) => setPassword(password)}
                  secureTextEntry={true}
                  placeholder=""
                  autoCapitalize="none"
                  value={password}
                />

                <View style={RED_ACTION_LINK}>
                  <TouchableOpacity onPress={() => navigation.navigate("resetpassword")}>
                    <Text style={RED_TEXT}>Forgot Password</Text>
                  </TouchableOpacity>
                </View>

                <View style={FOOTER_CONTENT}>
                  <Button
                    testID="next-screen-button"
                    style={CONTINUE}
                    textStyle={CONTINUE_TEXT}
                    tx="welcomeScreen.signIn"
                    onPress={showDashboard}
                  />
                  <TouchableOpacity onPress={() => navigation.navigate("signup")}>
                    <Text style={NORMAL_TEXT}>
                      Don't have an Account yet? <Text style={BLUE_TEXT}>Sign up</Text>
                    </Text>
                  </TouchableOpacity>
                </View>
     
          </SafeAreaView>
        </View>
      </ImageBackground>
    )
  },
)

// 请参阅下面的导航

import React, { useEffect } from "react"
import { useColorScheme } from "react-native"
import { NavigationContainer, DefaultTheme, DarkTheme } from "@react-navigation/native"
import { createNativeStackNavigator } from "@react-navigation/native-stack"
import {
  WelcomeScreen,
  DemoScreen,
  DemoListScreen,
  SignupScreen,
  LoginScreen,
  ResetPasswordScreen,
  DashboardScreen,
  HomeScreen,
  ArticleScreen,
} from "../screens"
import { navigationRef } from "./navigation-utilities"
import { useTokenStore, TokenStoreContext } from "../utils/storage/token"

/**
 * This type allows TypeScript to know what routes are defined in this navigator
 * as well as what properties (if any) they might take when navigating to them.
 *
 * If no params are allowed, pass through `undefined`. Generally speaking, we
 * recommend using your MobX-State-Tree store(s) to keep application state
 * rather than passing state through navigation params.
 *
 * For more information, see this documentation:
 *   https://reactnavigation.org/docs/params/
 *   https://reactnavigation.org/docs/typescript#type-checking-the-navigator
 */
export type NavigatorParamList = {
  welcome: undefined
  demo: undefined
  demoList: undefined
  login: undefined
  signup: undefined
  resetpassword: undefined
  dashboard: undefined
  home: undefined
}

// Documentation: https://reactnavigation.org/docs/stack-navigator/
const Stack = createNativeStackNavigator<NavigatorParamList>()

const AppStack = () => {
  const { getToken } = useTokenStore()
  const [userToken, setUserToken] = React.useState(false)

  useEffect(() => {
    console.log("<<<<< IS LOGGED IN STATE >>>>>>")
    console.log(userToken)
    console.log("<<<<< IS LOGGED IN STATE >>>>>>")
    setUserToken(getToken())
    console.log("<<<<< NEW TOKEN IN STATE >>>>>>")
    console.log(userToken)
    console.log("<<<<< NEW TOKEN IN STATE >>>>>>")
  }, [userToken])

  return (
    <Stack.Navigator
      screenOptions={{
        headerShown: false,
      }}
      initialRouteName="login"
    >
      {!userToken ? (
        <>
          <Stack.Screen name="login" component={LoginScreen} />
          <Stack.Screen name="signup" component={SignupScreen} />
          <Stack.Screen name="resetpassword" component={ResetPasswordScreen} />
          <Stack.Screen name="demo" component={DemoScreen} />
          <Stack.Screen name="demoList" component={DemoListScreen} />
          <Stack.Screen name="welcome" component={WelcomeScreen} />
        </>
      ) : (
        <>
          <Stack.Screen name="dashboard" component={DashboardScreen} />
        </>
      )}
    </Stack.Navigator>
  )
}

interface NavigationProps extends Partial<React.ComponentProps<typeof NavigationContainer>> {}

export const AppNavigator = (props: NavigationProps) => {
  const colorScheme = useColorScheme()
  return (
    <NavigationContainer
      ref={navigationRef}
      theme={colorScheme === "dark" ? DarkTheme : DefaultTheme}
      {...props}
    >
      <AppStack />
    </NavigationContainer>
  )
}

AppNavigator.displayName = "AppNavigator"

/**
 * A list of routes from which we're allowed to leave the app when
 * the user presses the back button on Android.
 *
 * Anything not on this list will be a standard `back` action in
 * react-navigation.
 *
 * `canExit` is used in ./app/app.tsx in the `useBackButtonHandler` hook.
 */
const exitRoutes = ["welcome"]
export const canExit = (routeName: string) => exitRoutes.includes(routeName)
// 下面是我的mobx商店文件

import { action, computed, makeObservable, observable } from "mobx";
import React from "react";

class TokenValue{
    token = false;
    constructor() {
        makeObservable(this, {
            token: observable,
            getToken: action,
            unsetToken: action,
            setToken: action
        })
      }

    setToken(){
        this.token = true;
    }

    unsetToken(){
        this.token = false;
    }

    getToken(){
        if(this.token === undefined)
            {
                return false;
            }else{
                return true;
            }
    }

}

 const tokenValueStore = new TokenValue();

 export const TokenStoreContext = React.createContext(tokenValueStore);
 export const useTokenStore = () => React.useContext(TokenStoreContext)

推荐答案

我最终使用的是Reaction-Redux而不是mobx,因为mobx不允许使用useSelector和Dispatch

这篇关于使用MOBX在Reaction本机中存储状态时,无法导航到不同的导航菜单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆