【问题标题】:Redux Navigation with Redux , navigating to home screen once authenticatedRedux Navigation with Redux ,一旦通过身份验证导航到主屏幕
【发布时间】:2018-11-25 05:43:02
【问题描述】:

我知道之前有人问过这个问题,但理想情况下,我希望将导航状态存储在 react 导航而不是 redux 中,我最近从 React-Native-Router-Flux 迁移并且能够调用导航与 react-navigation 不同,redux 操作本身内的操作

登录用户操作

export const loginUser = ({ email, password }) => {
  return dispatch => {
    dispatch({ type: LOGIN_USER });

    return AuthApi.login(email, password)
      .then(response => {
        return response.json();
      })
      .then(result => {
        if (result.ok) {
          // authenticated successfully
          dispatch(setLoginSuccess(result.auth_token));
          _saveItem("authToken", result.auth_token);
        } else {
          dispatch(setLoginFail(result.message));
        }
      });
  };
};

认证成功后有没有办法调用this.props.navigation.navigate('Home')

导航器

const AppStack = createStackNavigator(
  {
    Home: {
      screen: BottomTabNavigator,
      navigationOptions: {
        header: null
      }
    },
    Profile: {
      screen: ProfileScreen,
      navigationOptions: {
        header: null
      }
    },
    Quest: {
      screen: QuestScreen,
      navigationOptions: ({ navigation }) => ({
        title: "Quest Info",
        headerLeft: (
          <HeaderBackButton
            tintColor={"#FFF"}
            onPress={() => navigation.navigate("Home")}
          />
        ),
        headerStyle: {
          backgroundColor: "#E8536D",
          borderBottomColor: "transparent",
          borderBottomWidth: 0,
          elevation: 0,
          shadowOpacity: 0
        },
        headerTitleStyle: {
          fontWeight: "bold",
          color: "#FFF"
        }
      })
    },
    Test: {
      screen: TestScreen,
      navigationOptions: {
        header: null
      }
    }
  },
  {
    initialRouteName: "Home"
  }
);

const AuthStack = createStackNavigator(
  {
    Tutorial: {
      screen: TutorialScreen,
      navigationOptions: {
        header: null
      }
    },
    Login: {
      screen: LoginScreen,
      navigationOptions: {
        header: null
      }
    },
    Register: {
      screen: RegisterScreen,
      navigationOptions: ({ navigation }) => ({
        title: "Sign Up With Email",
        headerLeft: (
          <HeaderBackButton
            tintColor={"#FFF"}
            onPress={() => navigation.navigate("Login")}
          />
        ),
        headerStyle: {
          backgroundColor: "#E8536D",
          borderBottomColor: "transparent",
          borderBottomWidth: 0,
          elevation: 0,
          shadowOpacity: 0
        },
        headerTitleStyle: {
          fontWeight: "bold",
          color: "#FFF"
        }
      })
    },
    ResetPassword: {
      screen: ResetPasswordScreen,
      navigationOptions: ({ navigation }) => ({
        title: "Reset Your Password",
        headerLeft: (
          <HeaderBackButton
            tintColor={"#FFF"}
            onPress={() => navigation.navigate("Login")}
          />
        ),
        headerStyle: {
          backgroundColor: "#E8536D",
          borderBottomColor: "transparent",
          borderBottomWidth: 0,
          elevation: 0,
          shadowOpacity: 0
        },
        headerTitleStyle: {
          fontWeight: "bold",
          color: "#FFF"
        }
      })
    }
  },
  {
    initialRouteName: "Tutorial"
  }
);

export default (RootNavigator = () => {
  return createSwitchNavigator(
    {
      AuthLoading: AuthLoadingScreen,
      App: AppStack,
      Auth: AuthStack
    },
    {
      initialRouteName: "Auth"
    }
  );
});

授权减少器

import {
  EMAIL_CHANGED,
  PASSWORD_CHANGED,
  LOGIN_USER,
  LOGIN_USER_SUCCESS,
  LOGIN_USER_FAIL,
  SIGNUP_USER,
  SIGNUP_SUCCESS,
  SIGNUP_FAIL
} from "../actions/types";
const INITIAL_STATE = {
  email: "",
  password: "",
  user: null,
  error: "",
  isAuthenticated: false,
  loading: false,
  Authorization: null
};

export default (state = INITIAL_STATE, action) => {
  switch (action.type) {
    case EMAIL_CHANGED:
      // returns a new state with ...state by creating a new object
      return { ...state, error: "", email: action.payload };
    case PASSWORD_CHANGED:
      return { ...state, error: "", password: action.payload };
    case LOGIN_USER:
      return { ...state, loading: true, error: "" };
    case LOGIN_USER_SUCCESS:
      return {
        ...state,
        email: "",
        password: "",
        loading: false,
        isAuthenticated: true,
        error: "",
        Authorization: action.payload
      };
    case LOGIN_USER_FAIL:
      return {
        ...state,
        email: "",
        password: "",
        loading: false,
        error: action.payload
      };
    case SIGNUP_USER:
      return { ...state, loading: true, error: "" };
    case SIGNUP_SUCCESS:
      return {
        ...state,
        email: "",
        password: "",
        loading: false,
        isAuthenticated: true,
        Authorization: action.payload,
        error: ""
      };
    case SIGNUP_FAIL:
      return {
        ...state,
        email: "",
        password: "",
        loading: false,
        error: action.payload
      };
    default:
      return state;
  }
};

登录屏幕

loginUser = () => {
  const { email, password } = this.props;
  this.props.loginUser(
    { email, password },
  );
};

componentDidUpdate() {  
  if(this.props.isAuthenticated === true) {
    this.props.navigation.navigate('Home');
  }
};

const mapStateToProps = ({ auth }) => {
  const { email, password, error, loading, isAuthenticated } = auth;

  return { email, password, error, loading, isAuthenticated };
};

export default connect(
  mapStateToProps,
  {
    emailChanged,
    passwordChanged,
    loginUser
  }
)(LoginScreen);

【问题讨论】:

    标签: authentication react-native redux react-navigation


    【解决方案1】:

    是的,这是可能的,我使用与您在此处所做的完全相同的方法:带有 LoadingScreen、AuthStack 和 AppStack 的 SwichtNavigator。

    您只需要通过 react-redux 的连接助手将 RegisterScreen 连接到您的 redux 存储,并使用 mapStateToProps 挂钩存储的部分,一旦用户通过您的屏幕道具身份验证,该部分将被更新。然后你只需像这样使用 componentDidUpdate() :

    class RegisterScreen extends React.Component {
    
      ... 
    
      public componentDidUpdate(): void {
    
        if (this.props.isAuthenticated === true) {  
          this.props.navigation.navigate('Home');
        }
      }
    }
    
    const mapStateToProps = (state) => {
      return {
        isAuthenticated: state.isAuthenticated // or whatever your state property is called
      };
    };
    
    export default connect(mapStateToProps)(RegisterScreen);
    

    【讨论】:

    • 我一定是做错了什么。尽管连接到 auth reducer 并在成功验证后设置 isAuthenticated: true,但我的生命周期方法返回 false。你能展示你的 auth reducer 吗?我已经编辑了我的初始帖子以包含 Auth Reducer
    • 乍一看似乎是正确的。我的减速器不会真正帮助你,因为我没有使用布尔标志进行身份验证,但我有几个常量(我的身份验证流程涉及很多不同的步骤,因为我的客户端使用低级 TCP 套接字进行身份验证)
    • 你能看到你的状态吗?例如:React Native Debugger 将向您显示所有已调度的操作,您可以检查每个操作的状态
    • 是的,你是对的!我的承诺中有一个错误 result.ok 返回 undefined 导致它调度失败的登录操作。
    猜你喜欢
    • 2018-04-08
    • 1970-01-01
    • 2019-10-18
    • 1970-01-01
    • 2019-08-19
    • 2020-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多