连接 redux 功能不适用于 react-native

Mah*_*eem 7 reactjs react-native redux react-redux

我正在尝试使用 react-native 配置 redux 我在尝试从我的组件调用操作时遇到一个名为 undefined is not a function 的错误,似乎 action() 函数未正确调用,我无法访问状态为表单组件内的 prop。
这是我的代码:

索引.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);
Run Code Online (Sandbox Code Playgroud)

表单.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);
Run Code Online (Sandbox Code Playgroud)

index.js(在 actions 文件夹内)

    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 
        };
    };
Run Code Online (Sandbox Code Playgroud)

index.js(在reducers文件夹内)

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

export default combineReducers({
    auth: AuthReducer
    //   employeeForm: EmployeeFormReducer,
    //   employees: EmployeeReducer
});
Run Code Online (Sandbox Code Playgroud)

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;
      }
    };
Run Code Online (Sandbox Code Playgroud)

这是返回的错误

Cha*_*aka 7

我也面临这个问题并花了很多时间..这个问题在这个组件中不起作用 react-redux connect 。因为执行

export class Form extends Component
Run Code Online (Sandbox Code Playgroud)

因此不执行

export default connect(
    mapStateToProps,
    emailChanged,
)(Form);
Run Code Online (Sandbox Code Playgroud)

解决方案 :

删除导出关键字,例如:

 class Form extends Component
Run Code Online (Sandbox Code Playgroud)

并导入您必须使用此组件的位置

 import Form  from './src/components/Form';
Run Code Online (Sandbox Code Playgroud)

不要使用

 import { Form } from './src/components/Form';
Run Code Online (Sandbox Code Playgroud)

在这种情况下进行如下更改,

索引.android.js

  import Form  from './src/components/Form';
Run Code Online (Sandbox Code Playgroud)

表单.js

export class Form extends Component {
...
}
 export default connect(
        mapStateToProps,
        emailChanged ,
    )(Form);
Run Code Online (Sandbox Code Playgroud)

希望这对你有帮助......快乐编码......!


Mah*_*eem 0

最后我解决了这个错误,首先我改变了代码的结构,我将Provider和store直接放在index.android.js中,然后我改变了这个函数:

function mapDispatchToProps(dispatch) {
    return bindActionCreators({ emailChanged }, dispatch);
}
Run Code Online (Sandbox Code Playgroud)

对此:

function mapDispatchToProps (dispatch) {
   return {
    emailChanged: () => dispatch(emailChanged())
   }
}
Run Code Online (Sandbox Code Playgroud)

不使用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",
Run Code Online (Sandbox Code Playgroud)

还要确保您的 .babelrc 有:

{
"presets": ["react-native", "es2015", "stage-0"],
"sourceMaps": true,
"plugins": [
["transform-decorators-legacy"],
]
}
Run Code Online (Sandbox Code Playgroud)

需要考虑的重要注意事项:出于各种原因,React 和 Redux 团队通常不鼓励使用 connect() 作为装饰器。规范仍然不稳定,Babel 插件仍在变化,即使插件正常工作,从开发人员的角度来看,使用 connect() 作为装饰器也可能会导致意外的行为。

这对我有用,但如果它仍然不起作用,请尝试使用 connect() 作为函数而不是装饰器。

这些更改解决了错误!希望这会对您有所帮助。谢谢你们。