использовать рекомпозицию в редуксе

У меня есть компонент, который разработан с использованием реакции и редукции. Теперь, когда я хочу использовать recompose, я не понял организованного способа его использования с редуксом. Под организованным способом я имею в виду, что раньше у меня было две функции, такие как mapStateToProps и mapDispatchToProps, и они были заключены в connect HOC, что, на мой взгляд, делает код более читаемым и чистым. Мой вопрос в том, как мне сделать то же самое, что и для редукции? Я не мог найти при поиске этого пути, поэтому я не уверен, есть ли способ или нет, может ли кто-нибудь помочь мне, поделившись им, пожалуйста?

Вот мой код

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

для handleChange и handleSubmit я могу использовать withHandler и withState, но для mapStateToProps и mapDispatchToProps я не знаком.


person Serenity    schedule 21.06.2018    source источник
comment
Какую часть вы хотите организовать?   -  person WooodHead.com    schedule 21.06.2018
comment
mapStateToProps и mapDispatchToProps в recmpose.   -  person Serenity    schedule 21.06.2018


Ответы (2)


Чтобы напрямую ответить на ваш вопрос:

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

Бонус! ????

Вам не нужен отдельный mapDispatchToProps при использовании recompose. Нам нравится использовать withHandlers Recompose для всех обработчиков, включая отправки Redux.

Похоже на это.

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);
person GollyJer    schedule 21.06.2018
comment
Спасибо за бонус. Я не был знаком с этим. - person Serenity; 22.06.2018

для картыStateToProps:

Вы можете использовать reselect, чтобы переместить логику селектора в другой файл, а затем поделиться селекторами между компонентами.

для картыDispatchToProps:

вы можете использовать redux-thunk или redux-saga для перемещения асинхронной логики в отдельные файлы.

person WooodHead.com    schedule 21.06.2018
comment
Извините, мой вопрос не смог вас прояснить. Я нашел решение. он должен быть составлен (connect (mapStateToProps, mapDispatchToProps), withState, withHandler). Спасибо за вашу заботу. - person Serenity; 21.06.2018
comment
Отлично, мне тоже помогает. - person WooodHead.com; 21.06.2018