React Native Auth 与 React Navigation 和 Redux

Posted

技术标签:

【中文标题】React Native Auth 与 React Navigation 和 Redux【英文标题】:React Native Auth with React Navigation and Redux 【发布时间】:2017-11-28 19:53:17 【问题描述】:

我刚刚开始将 Redux 集成到我的第一个 React Native (Expo.io) 项目中。我的登录在 Redux 上工作得很好,但是当我尝试在我的应用程序的一个屏幕上创建一个注销按钮时,它实际上一加载它就会触发注销调度。我想我一定是误解了 Redux 连接和 mapDispatchToProps 的工作方式。我已经阅读了很多次文档,但仍然卡住了。这是处于非工作状态的代码。

登录 - 在我在个人资料页面上添加注销调度之前一直有效

import  connect  from "react-redux";
import React,  Component  from "react";
import 
    Button,
    View,
    Text,
    ActivityIndicator,
    Alert,
    FlatList
 from "react-native";
import  NavigationActions  from "react-navigation";
import  SocialIcon, Card  from "react-native-elements";
import Reactotron from "reactotron-react-native";

import  logIn  from "../actions";
import  signIn  from "../components/Auth";

class SignIn extends Component 
    async handleClick() 
        res = await signIn();
        if (res != false) 
            this.props.logIn(res.token);
         else 
            console.log("Login Failed");
        
    

    render() 
        return (
            <View style= paddingVertical: 20 >
                <Card title="finis Requires A Facebook Account To Operate">
                    <SocialIcon
                        title="Fred"
                        button
                        type="facebook"
                        onPress=() => this.handleClick()
                    />
                </Card>
            </View>
        );
    


const mapDispatchToProps = dispatch => 
    return 
        logIn: fbToken => 
            dispatch(logIn(fbToken));
        
    ;
;

LoginScreen = connect(null, mapDispatchToProps)(SignIn);

export default LoginScreen;

减速器

import  combineReducers  from "redux";
import Reactotron from "reactotron-react-native";

import  LOG_IN, LOG_OUT, ADD_PHONE_CONTACTS  from "../actions/actions";

const initialState = 
    signedIn: false,
    fbToken: "fred",
    test: undefined,
    phoneContacts: 
;

const finis = combineReducers(
    auth,
    phoneContacts
);

function auth(state = initialState, action) 
    switch (action.type) 
        case LOG_IN:
            Reactotron.log("LOG IN");
            return 
                ...state,
                signedIn: true,
                fbToken: action.fbToken
            ;
        case LOG_OUT:
            Reactotron.log("LOG OUT");
            return 
                ...state,
                signedIn: false,
                fbToken: undefined
            ;

        default:
            return state;
    


function phoneContacts(state = [], action) 
    switch (action.type) 
        case ADD_PHONE_CONTACTS:
            console.log("Adding Contacts");
            return 
                ...state,
                phoneContacts: action.phoneContacts
            ;
        default:
            return state;
    


export default finis;

个人资料不工作。在不按下按钮的情况下触发 LOG_OUT 操作。

import React,  Component  from "react";
import  Button, Card  from "react-native-elements";
import  View, Text, ActivityIndicator, AsyncStorage  from "react-native";
import  MapView  from "expo";
import  connect  from "react-redux";
import  bindActionCreators  from "redux";
import  SimpleLineIcons  from "@expo/vector-icons";
import Reactotron from "reactotron-react-native";

import * as ActionCreators from "../actions";
import  signOut  from "../components/Auth";

class ProfileWrap extends Component 
    handleClick() 
        Reactotron.log(this.Actions);
        this.props.logOut();
    

    render() 
        return (
            <View style= paddingVertical: 20 >
                <Card title="Profile">
                    <View
                        style=
                            backgroundColor: "#bcbec1",
                            alignItems: "center",
                            justifyContent: "center",
                            width: 80,
                            height: 80,
                            borderRadius: 40,
                            alignSelf: "center",
                            marginBottom: 20
                        
                    >
                        <Text style= color: "white", fontSize: 28 >JD</Text>
                    </View>
                    <Button title="Log Out" onPress=this.handleClick />
                </Card>
            </View>
        );
    


mapDispatchToProps = dispatch => 
    return  
        logOut: dispatch(logOut())
    ;
;

const Profile = connect(null, mapDispatchToProps)(ProfileWrap);

export default Profile;

任何帮助都将不胜感激,即使它告诉我我做错了整个事情:) 一直在这几个小时。

新的 Profile.js - 给出无法读取未定义的属性“logOut”

import React,  Component  from "react";
import  Button, Card  from "react-native-elements";
import  View, Text, ActivityIndicator, AsyncStorage  from "react-native";
import  MapView  from "expo";
import  connect  from "react-redux";
import  SimpleLineIcons  from "@expo/vector-icons";

import  logOut  from "../actions";
import  signOut  from "../components/Auth";

class ProfileWrap extends Component 
    handleClick() 
        console.log(this.props);
        this.props.logOut();
    

    render() 
        return (
            <View style= paddingVertical: 20 >
                <Card title="Profile">
                    <View
                        style=
                            backgroundColor: "#bcbec1",
                            alignItems: "center",
                            justifyContent: "center",
                            width: 80,
                            height: 80,
                            borderRadius: 40,
                            alignSelf: "center",
                            marginBottom: 20
                        
                    >
                        <Text style= color: "white", fontSize: 28 >JD</Text>
                    </View>
                    <Button title="Log Out" onPress=this.handleClick />
                </Card>
            </View>
        );
    


const mapDispatchToProps = dispatch => 
    return 
        logOut: function() 
            dispatch(logOut());
        
    ;
;

const Profile = connect(null, mapDispatchToProps)(ProfileWrap);

export default Profile;

【问题讨论】:

【参考方案1】:

您的mapDispatchToProps 应该返回一个带有函数 的对象。按照您现在的方式,logOut() 将立即被调用,因为它不在函数内部。将其更改为此应该可以解决它:

const mapDispatchToProps = dispatch => 
    return  
        logOut: function () 
            dispatch(logOut());
        
    ;
;

这是一种更简洁的方法:

const mapDispatchToProps = dispatch => ( 
    logOut() 
        dispatch(logOut());
    
);

另外,您在mapDispatchToProps 前面缺少const,但这应该不会影响任何事情。

编辑:

您现在不必使用它,但将来会有所帮助 - 如果您的组件仅使用 render 方法,您可以将其更改为无状态功能组件。目前推荐的方法是尽可能创建组件:

const ProfileWrap = props => (
  <View style= paddingVertical: 20 >
      <Card title="Profile">
          <View
              style=
                  backgroundColor: "#bcbec1",
                  alignItems: "center",
                  justifyContent: "center",
                  width: 80,
                  height: 80,
                  borderRadius: 40,
                  alignSelf: "center",
                  marginBottom: 20
              
          >
              <Text style= color: "white", fontSize: 28 >JD</Text>
          </View>
          <Button title="Log Out" onPress=props.logOut />
      </Card>
  </View>
);

【讨论】:

感谢多诺万!不幸的是,我现在收到“无法读取未定义的属性 'logOut'” 当您单击“注销”按钮时会发生这种情况吗?看起来 logOut 在此文件中未定义。您可以将dispatch 行更改为dispatch(ActionCreators.logOut())。但是,我认为这不会解决您遇到的特定错误(仍在调查中) 我在原帖中添加了一个新的 profile.js,你能看出我哪里出错了吗?它似乎没有映射道具 我认为这是因为handleClick 没有绑定到组件。如果您将按钮更改为:&lt;Button title="Log Out" onPress=this.props.logOut /&gt;,它是否有效? 完成,非常感谢

以上是关于React Native Auth 与 React Navigation 和 Redux的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在 React Native 中使用 Digest Auth 和 Fetch?

AWS Amplify Auth Login 从 React Native 上的 React Native Webview

React-Native Firebase Phone Auth 冻结 iPhone

RNAppAuth,iOS 构建失败,未知类型名称“命名空间”,react-native-app-auth

React-native google auth android DEVELOPER_ERROR 代码 10

React Native 中的 Auth0 刷新令牌失败并显示 401