使用React Navigation和Redux实现Native Auth

时间:2017-06-26 00:38:03

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

我刚刚开始将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;

任何帮助都会受到赞赏,即使它告诉我我做错了所有的事情:)已经持续数小时了。

NEW Profile.js - Gives无法读取未定义的属性'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 个答案:

答案 0 :(得分:1)

您的mapDispatchToProps应该返回一个带有功能的对象。你现在拥有它的方式,logOut()将被立即调用,因为它不在函数内部。将其更改为此应修复它:

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

这是一种更简洁的方法:

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

此外,您在const前面遗失了mapDispatchToProps,但这不会影响任何内容。

编辑:

您现在不必使用它,但它将来会有所帮助 - 如果您的组件仅使用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>
);