【问题标题】:React Native Auth with React Navigation and ReduxReact Native Auth 与 React Navigation 和 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;

【问题讨论】:

    标签: react-native redux react-redux react-navigation expo


    【解决方案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;,它是否有效?
    • 完成,非常感谢
    猜你喜欢
    • 1970-01-01
    • 2018-05-23
    • 2018-02-19
    • 1970-01-01
    • 2019-10-22
    • 2017-10-24
    • 1970-01-01
    • 2019-02-28
    • 2017-10-11
    相关资源
    最近更新 更多