我正在尝试使用 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;
}
}
答案 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的应用预览
答案 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';
但是当动作列表过长时,像这样使用它们会很奇怪!