我正在尝试将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: }
答案 0 :(得分:2)
您需要在类声明
之前删除带前缀的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导入其他位置作为默认导入
答案 1 :(得分:1)
对我而言似乎是由于babel设置或其他原因导致的混乱模块导入。您可以在浏览器抱怨的行上设置断点,并在控制台中评估_LoginActions.loginAction
。确保它未定义。
在范围内找到_LoginActions,问题就很明显了。如果没有,请告诉我们相应的范围是什么样的。 Scope
是chrome dev工具调试程序源代码部分