簡體   English   中英

TypeError:undefined不是函數(評估調度)

[英]TypeError: undefined is not a function (evaluating dispatch)

我試圖將React Redux與React Native結合在一起,並且在調試程序時遇到了這個奇怪的錯誤:

TypeError: undefined is not a function (evaluating 'dispatch((0, _LoginActions.loginAction)(inputFormProp))')

運行該程序后,立即從組件的登錄功能中觸發了該錯誤,但我不知道為什么會有該錯誤。

這是我的組件代碼:

import React, { Component } from 'react';
import { Text, View, TextInput, ActivityIndicator, TouchableHighlight } from 'react-native';
import { getLogger, issueToText } from '../core/utils';
import styles from '../core/styles';
import { Card, Button, FormLabel, FormInput } from "react-native-elements";
import { connect } from 'react-redux'
import { loginAction } from '../actions/LoginActions'

export class LoginComponent extends Component {
constructor(props) {
    super(props);
    this.login = this.login.bind(this)
}

render() {
    const { error, isLoading } = this.props;

    const inputFormProp = {
        username: '',
        password: ''
    };

    return (
        <View style={{ paddingVertical: 20 }}>
            <Card>
                <FormLabel>Email</FormLabel>
                <FormInput value={inputFormProp.username} onChangeText={(text) => inputFormProp.username = text} />
                <FormLabel>Password</FormLabel>
                <FormInput value={inputFormProp.password} onChangeText={(text) => inputFormProp.password = text} />

                <Button
                    buttonStyle={{ marginTop: 20 }}
                    backgroundColor="#03A9F4"
                    title="SIGN IN"
                    onPress={this.login(inputFormProp)}
                />
            </Card>
            <ActivityIndicator animating={this.props.isLoading} style={styles.activityIndicator} size="large" />
        </View>
    );
}


login(inputFormProp) {
    const { store } = this.props.screenProps.store;

    const { dispatch } = this.props

    dispatch(loginAction(inputFormProp))
        .then(() => {
            if (this.props.error === null && this.props.isLoading === false) {
                if (store.getState().auth.token) {
                    this.props.navigation.navigate('ProductList', { token: store.getState().auth.token });
                }
            }
        })
        .catch(error => {
        });
}


}

function mapStateToProps(state) {
const { error, isLoading } = state.auth

return {
    error,
    isLoading,
}
}

export default connect(mapStateToProps)(LoginComponent)

這是我的app.js代碼:

const initialState = {
  auth: { isLoading: false, error: null },
};


const rootReducer = combineReducers({ product: productReducer, auth: authReducer 
});

const store = createStore(rootReducer, initialState, applyMiddleware(thunk, 
createLogger()));

export const MyNavigator = StackNavigator({
  Login: { screen: LoginComponent },
  ProductList: { screen: ProductList },
});



export default class App extends Component {
  render() {
    return (
      <MyNavigator screenProps={{ store: { store } }} />
    );
  }
};

從我已經搜索過的錯誤中看來,原因似乎是組件中的connect()函數,但我不知道它到底出了什么問題。

這是我的目錄結構:

在此處輸入圖片說明

這是LoginActions文件:

import { loginService } from '../services/LoginService'

export function loginAction(data) {
    return dispatch => {
        loginService(data);
    }
}

這是LoginService文件:

import { httpApiUrl } from '../core/api';
import { getLogger } from "../core/utils";
import { Alert } from 'react-native';
const log = getLogger('auth/service');


export const loginService = (user) => (dispatch) => {
dispatch({ type: 'LOGIN_STARTED' });
return fetch(`${httpApiUrl}/api/userdata/verify`, {
    method: 'POST',
    headers: {
        'Accept': '*/*',
        'Content-Type': 'application/json',
    },
    body: JSON.stringify(user)
})
    .then((response) => {
        if (!response.ok) {
            Alert.alert('ERROR', 'User or password is incorrect');
            dispatch({ type: 'LOGIN_FAILED', data: 'User or password is incorrect' });
        }
        else return response;
    }).then((response) => response.json).then((response) => {
        dispatch({ type: 'LOGIN_SUCCEEDED', data: response.json });

    })
    .catch(error => {
        dispatch({ type: 'LOGIN_FAILED', data: error.message });
    });
};

這是this.props的輸出

21:10:48: Object {
21:10:48:   "navigation": Object {
21:10:48:     "dispatch": [Function anonymous],
21:10:48:     "goBack": [Function goBack],
21:10:48:     "navigate": [Function navigate],
21:10:48:     "setParams": [Function setParams],
21:10:48:     "state": Object {
21:10:48:       "key": "Init-id-1515093047465-0",
21:10:48:       "routeName": "Login",
21:10:48:     },
21:10:48:   },
21:10:48:   "screenProps": Object {
21:10:48:     "store": Object {
21:10:48:       "store": Object {
21:10:48:         "@@observable": [Function observable],
21:10:48:         "dispatch": [Function anonymous],
21:10:48:         "getState": [Function getState],
21:10:48:         "replaceReducer": [Function replaceReducer],
21:10:48:         "subscribe": [Function subscribe],
21:10:48:       },
21:10:48:     },
21:10:48:   },
21:10:48: }

您需要在類聲明之前刪除帶前綴的export關鍵字

class LoginComponent extends Component { //<--- export was present here 
constructor(props) {
    super(props);
    this.login = this.login.bind(this)
}

render() {
    const { error, isLoading } = this.props;

    const inputFormProp = {
        username: '',
        password: ''
    };

    return (
        <View style={{ paddingVertical: 20 }}>
            <Card>
                <FormLabel>Email</FormLabel>
                <FormInput value={inputFormProp.username} onChangeText={(text) => inputFormProp.username = text} />
                <FormLabel>Password</FormLabel>
                <FormInput value={inputFormProp.password} onChangeText={(text) => inputFormProp.password = text} />

                <Button
                    buttonStyle={{ marginTop: 20 }}
                    backgroundColor="#03A9F4"
                    title="SIGN IN"
                    onPress={this.login(inputFormProp)}
                />
            </Card>
            <ActivityIndicator animating={this.props.isLoading} style={styles.activityIndicator} size="large" />
        </View>
    );
}


login(inputFormProp) {
    const { store } = this.props.screenProps.store;

    const { dispatch } = this.props

    dispatch(loginAction(inputFormProp))
        .then(() => {
            if (this.props.error === null && this.props.isLoading === false) {
                if (store.getState().auth.token) {
                    this.props.navigation.navigate('ProductList', { token: store.getState().auth.token });
                }
            }
        })
        .catch(error => {
        });
}


}

function mapStateToProps(state) {
const { error, isLoading } = state.auth

return {
    error,
    isLoading,
}
}

export default connect(mapStateToProps)(LoginComponent)

還要確保您將LoginComponent導入為默認導入。

在我看來,由於babel設置或其他原因,導致模塊導入混亂。 您可以在瀏覽器抱怨的行上設置一個斷點,並在控制台中評估_LoginActions.loginAction 確保未定義。

比在范圍內找到_LoginActions,問題將顯而易見。 如果不是,那么請讓我們知道相應范圍的外觀。 Scope是chrome dev工具調試器“來源”部分中的標簽

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM