Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

connect redux function is not working with react-native

I'm trying to configure redux with react-native I face an error called undefined is not a function when try to call an action from my component , It seems that action() function is not called correctly , I can't access state as prop inside the form component.
This is my code :

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 protected]"
                    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 (inside actions folder )

    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(inside reducers folder)

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;
      }
    };

This is the error returned

like image 322
Mahmoud Abd AL Kareem Avatar asked Aug 29 '17 08:08

Mahmoud Abd AL Kareem


2 Answers

I also face this problem and spend lot of time.. This issue is not working react-redux connect in this component. Because excute

export class Form extends Component

Therefore not execute the

export default connect(
    mapStateToProps,
    emailChanged,
)(Form);

Solution :

remove the export keyword eg :

 class Form extends Component

and import where this component you must use

 import Form  from './src/components/Form';

Don't use

 import { Form } from './src/components/Form';

in this case make changes as follows,

index.android.js

  import Form  from './src/components/Form';

Form.js

export class Form extends Component {
...
}
 export default connect(
        mapStateToProps,
        emailChanged ,
    )(Form);

Hope this is helpful for you... Happy Coding...!

like image 180
Chanaka Avatar answered Oct 17 '22 23:10

Chanaka


Try just passing emailChanged directly.

return bindActionCreators(emailChanged, dispatch);

like image 39
basudz Avatar answered Oct 17 '22 22:10

basudz