Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

use recompose in redux

I have a component which is developed using react and redux. Now that i want to use recompose, I did not understand the organized way to use it with the redux. By organized way, I mean to say before i used to have two function like mapStateToProps and mapDispatchToProps and they are wrapped in connect HOC which makes code look more readable and clean in my opinion. My question is how do i do the same like the way i was doing for the redux part ? I could not find when searching for that way so I am not sure if there is a way or not if it is can anyone help me by sharing it, please?

Here is my code

import React from 'react';
import { connect } from 'react-redux';

const mapStateToProps = state => ({
  loginData: state.loginData,
});

const mapDispatchToProps = dispatch => ({
  login: user => dispatch(login(user)),
});

class Login extends React.Component<{ login: Function }> {
  state = {
    error: false,
    user: {
      email: '',
      password: '',
    },
  };

  handleChange = (e) => {
    const { name, value } = e.target;
    this.setState({ user: { ...this.state.user, [name]: value } });
  };

  handleSubmit = (e) => {
    e.preventDefault();
    this.props.login(this.state.user);
  };

  renderError() {
    if (this.state.error) {
      return (
        <ErrorMessage>
          The following email is not associated with us. Please create an
          account to use our service
        </ErrorMessage>
      );
    }
    return <div />;
  }
  render() {
    const { user } = this.state;
    return (
      <WhitePart>
        <UpperPart>
          <TitleContainer>
            <TitleText>Login</TitleText>
          </TitleContainer>
          {this.renderError()}
          <Form>
            <form onSubmit={this.handleSubmit}>
              <StyledField
                label="Email"
                id="email"
                name="email"
                type="text"
                value={user.email}
                placeholder="Email"
                className="input-field"
                component={GTextField}
                onChange={this.handleChange}
                style={{
                  marginBottom: '20px',
                }}
                required
                fullWidth
              />
              <StyledField
                label="Password"
                id="password"
                name="password"
                type="password"
                value={user.password}
                placeholder="Password"
                className="input-field"
                component={GPasswordField}
                onChange={this.handleChange}
                required
                fullWidth
              />
              <ButtonContainer>
                <PrimaryButton
                  type="submit"
                  style={{
                    textTransform: 'none',
                    fontFamily: 'Lato',
                    fontWeight: 300,
                  }}
                >
                  Login
                </PrimaryButton>
              </ButtonContainer>
            </form>
          </Form>
        </UpperPart>
      </WhitePart>
    );
  }
}

export default connect(
  mapStateToProps,
  mapDispatchToProps,
)(Login);

for handleChange and handleSubmit i can do using withHandler and withState but for mapStateToProps and mapDispatchToProps i am not familiar.

like image 997
Serenity Avatar asked Jun 21 '18 01:06

Serenity


People also ask

How does recompose work?

The Compose framework can intelligently recompose only the components that changed. Every time the button is clicked, the caller updates the value of clicks . Compose calls the lambda with the Text function again to show the new value; this process is called recomposition.

What is recompose used for?

Recompose allows us to write many smaller higher-order components and then we compose all those components together to get the desired component. It improves both readability and the maintainability of the code.


1 Answers

To directly answer your question:

export default compose(
  connect(
    mapStateToProps,
    mapDispatchToProps
  ),
  withStateHandlers,
  withHandler,
)(Login);

Bonus! 🙂

You don't need a separate mapDispatchToProps when using recompose. We like to use Recompose's withHandlers for all handlers, including Redux dispatches.

It looks like this.

import React from 'react';
import { connect } from 'react-redux';
import { signUpUser, loginUser } from './someActionsFile';

const LandingScreen = props => (
  <ButtonContainer>
    <Button title="Sign Up" onPress={props.dispatchSignUpUser} />
    <Button title="Log In" onPress={props.dispatchLoginUser} />
    <Button title="Say Hi!!" onPress={props.sayHi} />
  </ButtonContainer>
);

const mapStateToProps = state => ({
   loginData: state.loginData,
});

const myHandlers = withHandlers({
  dispatchSignUpUser: ({ dispatch }) => () => {
    dispatch(signUpUser());
  },
  dispatchLoginUser: ({ dispatch }) => () => {
    dispatch(loginUser());
  },
  sayHi: () => () => {
    console.log('Hi!!');
  }
});

export default compose(
  connect(mapStateToProps), // Once connect() is composed `dispatch` is prop.
  myHandlers
)(LandingScreen);
like image 76
GollyJer Avatar answered Sep 19 '22 11:09

GollyJer