我尝试使用react-native配置redux我遇到一个名为undefined的错误,当尝试从我的组件调用一个动作时,它不是一个函数,
似乎没有正确调用action()函数,我无法在表单组件中作为prop访问状态。
这是我的代码:
index.android.js
import React, { Component } from 'react';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
// import ReduxThunk from 'redux-thunk';
import reducers from './src/reducers';
import { Form } from './src/components/Form';
import { AppRegistry } from 'react-native';
export class App extends Component {
componentWillMount() {
//here we will handle firebase sutup process for the authntication purpose .
}
render() {
const store = createStore(reducers);
return (
<Provider store={store}>
<Form />
</Provider>
);
}
}
const styles = {
main: {
flex: 1,
flexDirection: 'column',
justifyContent: 'flex-start',
}
};
AppRegistry.registerComponent('test', () => App);
Form.js
import React, { Component } from "react";
import { connect } from "react-redux";
import { bindActionCreators } from "redux";
import { Image } from "react-native";
import { emailChanged } from "../actions";
import {
Container,
ContainerSection,
Button,
Input
} from ".././components/common";
export class Form extends Component {
onEmailChange(text) {
//call the action creator for the email
this.props.emailChanged(text);
}
onPasswordChange(text) {
//call the action creator for the password
}
onButtonPress() {
//do something
}
renderButton() {
return <Button onPress={this.onButtonPress.bind(this)}>Log in</Button>;
}
render() {
return (
<Container>
<ContainerSection>
<Image source={require("../../images/logo.png")} />
</ContainerSection>
<ContainerSection>
{/* email input */}
<Input
label="Email"
placeholder="email@gmail.com"
value={this.props.email}
onChangeText={this.onEmailChange.bind(this)}
keyboardType="email-address"
/>
</ContainerSection>
<ContainerSection>
{/* password input */}
<Input
label="password"
placeholder="password"
value={this.props.password}
onChangeText={this.onPasswordChange.bind(this)}
secure
/>
</ContainerSection>
<ContainerSection>{this.renderButton()}</ContainerSection>
</Container>
);
}
}
const mapStateToProps = state => {
return {
email: state.auth.email,
password: state.auth.password
};
};
function mapDispatchToProps(dispatch) {
return bindActionCreators({ emailChanged }, dispatch);
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(Form);
index.js(内部操作文件夹)
import { EMAIL_CHANGED, PASSWORD_CHANGED } from './types';
//it is an action creator
export const emailChanged = (text) => {
return {
type: EMAIL_CHANGED,
payload: text
};
};
//it is an action creator
export const passwordChanged = (text) => {
return {
type: PASSWORD_CHANGED,
payload: text
};
};
index.js(在reducers文件夹中)
import { combineReducers } from 'redux';
import AuthReducer from './AuthReducer';
export default combineReducers({
auth: AuthReducer
// employeeForm: EmployeeFormReducer,
// employees: EmployeeReducer
});
AuthReducer.js
import {
EMAIL_CHANGED,
PASSWORD_CHANGED
} from '../actions/types';
const INITIAL_STATE = {
email: '',
password: ''
};
export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case EMAIL_CHANGED:
return { ...state, email: action.payload };
case PASSWORD_CHANGED:
return { ...state, password: action.payload };
default:
return state;
}
};
答案 0 :(得分:4)
我也面临这个问题,并花费大量时间。.这个问题在该组件中无法正常工作。因为
export class Form extents Component
因此不要执行
export default connect(
mapStateToProps,
emailChanged ,
)(Form);
解决方案:
删除导出关键字 例如:
class Form extents Component
并导入您必须使用的组件
的位置 import Form from './src/components/Form';
请勿使用
import { Form } from './src/components/Form';
在这种情况下,请进行以下更改,
index.android.js
import Form from './src/components/Form';
Form.js
export class Form extends Component {
...
}
export default connect(
mapStateToProps,
emailChanged ,
)(Form);
希望这对您有帮助... 编码愉快!!
答案 1 :(得分:0)
尝试从任何组件使用调度调用。像这样
<强> Form.js 强>
this.props.dispatch(emailChanged(text));
答案 2 :(得分:0)
尝试直接传递emailChanged。
返回bindActionCreators(emailChanged,dispatch);
答案 3 :(得分:0)
请在 Form.js
中尝试此操作 import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { Image } from 'react-native';
import { emailChanged } from '../actions';
import { Container, ContainerSection, Button, Input } from '.././components/common';
export class Form extends Component {
constructor(props) {
super(props)
this.onPasswordChange= this.onPasswordChange.bind(this)
}
onEmailChange(text) {
//call the action creator for the email
this.props.emailChanged(text);
}
onPasswordChange(text) {
//call the action creator for the password
}
onButtonPress() {
//do something
}
renderButton() {
return (
<Button onPress={this.onButtonPress.bind(this)}>
Log in
</Button>
);
}
render() {
return (
<Container>
<ContainerSection>
<Image source={require('../../images/logo.png')} />
</ContainerSection>
<ContainerSection>
{/* email input */}
<Input
label="Email"
placeholder="email@gmail.com"
value={this.props.email}
onChangeText={this.onEmailChange.bind(this)}
keyboardType="email-address"
/>
</ContainerSection>
<ContainerSection>
{/* password input */}
<Input
label="password"
placeholder="password"
value={this.props.password}
onChangeText={this.onPasswordChange}
secure
/>
</ContainerSection>
<ContainerSection>
{this.renderButton()}
</ContainerSection>
</Container>
);
}
}
const mapStateToProps = state => {
return {
email: state.auth.email,
password: state.auth.password
};
};
FlipCardWithImage.propTypes = {
emailChanged : PropTypes.func,
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({ emailChanged }, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(Form);
答案 4 :(得分:0)
最后我解决了错误,首先我改变了代码的结构,我将Provider和store存储在index.android.js直接,然后我更改了这个函数:
function mapDispatchToProps(dispatch) {
return bindActionCreators({ emailChanged }, dispatch);
}
到此:
function mapDispatchToProps (dispatch) {
return {
emailChanged: () => dispatch(emailChanged())
}
}
不使用bindActionCreators
然后我使用yarn add安装了依赖项,
感谢Sacha Best,您可能还需要确保通过npm安装以下软件包:
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react-native": "^3.0.2",
"babel-preset-stage-0": "^6.24.1",
还要确保你的.babelrc:
{
"presets": ["react-native", "es2015", "stage-0"],
"sourceMaps": true,
"plugins": [
["transform-decorators-legacy"],
]
}
要考虑的重要注意事项:由于各种原因,React和Redux团队通常都不鼓励使用connect()作为装饰器。规范仍然不稳定,Babel插件仍然在变化,即使插件工作,使用connect()作为装饰器也会导致开发人员的意外行为。
这对我有用,但如果它仍然无法使用,请尝试使用connect()作为函数而不是装饰器。
这些变化解决了错误!希望这会对你有所帮助。 谢谢你们。
答案 5 :(得分:0)
昨天发生了同样的事情。但是,当我将所有代码文件复制到以前的项目时,它起作用了。所以它必须是安装损坏的东西,因为安装已经使用相同的包以相同的方式完成。在一个项目中,连接起作用,而在另一个项目中,它不起作用。