Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React-redux get props or state in mapDispatchToProps

please excuse potentially noob question, am new to react and react-redux.

I have a component representing a login screen currently. One of its props is "login", a dictionary that contains the email and password. After defining the component, I use the react-redux library to connect it with the store like so:

const mapStateToProps = (state) => {
  return {
    rootNav: state.rootNav,
    login: state.login,
  };
};

const mapDispatchToProps = (dispatch, ownProps) => {
  return {
    onLoginClick: () => {
      // TODO: actually get the login credentials from the view
      dispatch(actions.submitLogin('testuser', 'testpw'));
      dispatch(actions.changeRootNav(rootNavs.OVERVIEW_NAV))
    },
    onEmailUpdate: (email) => dispatch(actions.updateEmail(email)),
    onPasswordUpdate: (password) => dispatch(actions.updatePassword(password)),
  };
};

Obviously, in the line dispatch(actions.submitLogin('testuser', 'testpw')); I want to have the real email and password submitted as a payload with the action. But I don't understand how I should be accessing it from the component (i.e. I can't just use this.props.login) or if/how I should be accessing it from the store (where would I pass the store in?)

Any clarification would be extremely helpful!

like image 879
baisang Avatar asked Jun 15 '16 22:06

baisang


1 Answers

I think this can be handled in two ways. mapDispatchToProps is passed as the second argument to the react-redux connect function. It gives the connected component access to certain action creators. In this case you're giving it the action creators onLoginClick, onEmailUpdate, and onPAsswordUpdate.

Those functions are now accessible in your component via this.props.onLoginClick, this.props.onEmailUpdate etc. An easy solution is to create an onClick event on your login button, or onSubmit of the login form. If you're updating your Email and Password on your redux state and passing them to this component as props you can do something like this:

In your login class:

login() {
  // get password and email from the props
  const pw = this.props.password;
  const email = this.props.email;
  // submit login action with email and password
  this.props.onLoginClick(email, password)
}

render() {
  <form onSubmit={this.login.bind(this)}>
      ...
  </form>  
}

And update mapDispatchToProps to have onLoginClick expect an email and password.

const mapDispatchToProps = (dispatch, ownProps) => {
  return {
    // update this action creator to take an email and password
    onLoginClick: (email, password) => {
      // TODO: actually get the login credentials from the view
      dispatch(actions.submitLogin(email, password));
      dispatch(actions.changeRootNav(rootNavs.OVERVIEW_NAV))
    },
    onEmailUpdate: (email) => dispatch(actions.updateEmail(email)),
    onPasswordUpdate: (password) => dispatch(actions.updatePassword(password)),
};

Option 2

Otherwise according to the react-redux docs here https://github.com/reactjs/react-redux/blob/master/docs/api.md you can also use the second argument of mapDispatchToProps, ownProps.

So you can change onLoginClick to look like this:

onLoginClick: () => {
  const email = ownProps.email;
  const password = ownProps.password;

  dispatch(actions.submitLogin(email, password));
  dispatch(actions.changeRootNav(rootNavs.OVERVIEW_NAV))
}

and on your form you can do this:

render() {
  <form onSubmit={this.props.onLoginClick}>
      ...
  </form>  

}

or if you want it to be only on a button click...

<button onClick={this.props.onLoginClick}>Login</button>
like image 136
jmancherje Avatar answered Nov 15 '22 09:11

jmancherje