如何修复:react-redux中的'e不是函数'错误

时间:2019-08-25 08:32:31

标签: javascript react-native redux react-redux

我正在尝试使用 expo 中的 redux react-native 中创建一个简单的登录表单。
我遵循了一些教程和redux文档,他们都以这种方式进行操作,但每次都会遇到此错误:
e不是函数
TypeError:e不是函数

小吃链接:https://snack.expo.io/@housein/reduxtest

代码:

'App.js':

import React, {Component} from 'react';
import { Text, View, StyleSheet } from 'react-native';
import {createStore} from 'redux';
import {Provider} from 'react-redux';
import reducers from './reducers';
import LoginForm from './components/LoginForm';

class App extends Component {
  render () {
    const store = createStore(reducers);
    return(
      <Provider store={store}>
        <View>
          <LoginForm />
        </View>
      </Provider>
    );
  }
}

export default App;

'components / LoginForm.js':

import React, { Component } from 'react';
import { View, TextInput, Text } from 'react-native';
import actions from '../actions';
import { connect } from 'react-redux';

class LoginForm extends Component {
  onEmailChange(text) {
    return this.props.emailChanged(text);
  }

  render() {
    return (
      <View >
        <Text >Email:</Text>
        <TextInput
          onChangeText={this.onEmailChange.bind(this)}
          value={this.props.e}
        />
      </View>
    );
  }
}

const mapStateToProps = state => {
  return {e : state.auth.email};
}

export default connect(mapStateToProps, actions)(LoginForm);

'actions / index.js':

export const emailChanged = (text) => {
  return {
    type: 'EMAIL_CHANGED',
    payload: text
  };
};

'reducers / index.js':

import {combineReducers} from 'redux';
import AuthReducer from './AuthReducer';

export default combineReducers({
  auth : AuthReducer
});

'reducers / AuthReducer.js':

const INIT_STATE = {email : ''}

export default (state=INIT_STATE, action) => {
  switch (action.type) {
    case 'EMAIL_CHANGED' : 
      return {...state, email  : action.payload};
    default : 
      return state;
  }
}

4 个答案:

答案 0 :(得分:1)

实际问题是,使用mapStateToProps通过错误“ e”的网络版本的“ snack.expo”不是一个函数时。您必须在Android或Ios中对其进行检查

我做了一些小改动

定义这样的操作

import {emailChanged} from '../actions';
const actions = {
  emailChanged: emailChanged
};

将flex:1添加到主要组件

<View style={{flex:1}}>
          <LoginForm />
        </View>

小吃链接:https://snack.expo.io/@mehran.khan/reduxtest

基于ANDROID的应用预览

enter image description here

答案 1 :(得分:0)

尝试像这样传播actions

mapDispatchToProps = () => { ... actions };

export default connect(mapStateToProps, mapDispatchToProps)(ComponentName);

话虽这么说,您的AuthReducer中有些我不喜欢的东西。那条线到底是做什么的.. ??

return {...state, email  : 'second'};

我将其更改为:

return {...state, email  : action.payload};

在您的组合减速器功能中:


export default reducers = () => combineReducers({
  auth : AuthReducer
});

尝试一下。我认为它将解决您的问题。虽然,我认为我缺少一些东西。

答案 2 :(得分:0)

LoginForm组件存在问题。

onChangeText属性需要一个函数。您需要在构造函数中绑定emailChanged方法或使用箭头功能。 您无需从onEmailChange方法返回任何内容。

减速器代码也有问题。

'components / LoginForm.js':

import React, { Component } from 'react';
import { View, TextInput, Text } from 'react-native';
import actions from '../actions';
import { connect } from 'react-redux';

class LoginForm extends Component {
  constructor() {
    this.onEmailChange = this.onEmailChange.bind(this);
  }

  onEmailChange(text) {
    this.props.emailChanged(text);
  }

  render() {
    return (
      <View >
        <Text >Email:</Text>
        <TextInput
          onChangeText={this.onEmailChange}
          value={this.props.e}
        />
      </View>
    );
  }
}

const mapStateToProps = state => {
  return {e : state.auth.email};
}

export default connect(mapStateToProps, actions)(LoginForm);

'reducers / AuthReducer.js':

const INIT_STATE = {email : ''}

export default (state=INIT_STATE, action) => {
  switch (action.type) {
    case 'EMAIL_CHANGED' : 
      return {...state, email: action.payload };
    default : 
      return state;
  }
}

答案 3 :(得分:0)

解决了,但没有以有利的方式解决。
添加了mapDispatchToProps并将其作为connect(,)()的第二个参数传递

const mapDispatchToProps = dispatch => {
  return {
    emailChanged : (text) => dispatch({
      type: 'EMAIL_CHANGED',
      payload: text
    })
  }
};

export default connect(mapStateToProps, mapDispatchToProps)(LoginForm);

并显然已删除import actions from '../actions'; 但是当动作列表过长时,像这样使用它们会很奇怪!