Создатели действий не отображаются в this.props с редукционной формой 6.0.0-rc.3

Когда я использовал редукс-форму 5.3.1, я смог получить доступ к своим создателям действий. Но так как мне понадобился Material-UI, я обновил его до 6.0.0-rc.3.

Изменения с 5.3.1 на 6.0.0:

  • Удалены поля из render():

const { handleSubmit, fields: { email, password, passwordConfirm }} = this.props;

  • Удалена проверка ошибок из-под входов:

{email.touched && email.error && <div className="error">{email.error}</div>}

  • Удален массив полей из экспорта по умолчанию:

export default reduxForm({ form: 'signup', fields: ['email', 'password', 'passwordConfirm'], validate }, mapStateToProps, actions)(Signup);

  • Добавлены обертки для компонентов Material-UI:

import { renderTextField, renderCheckbox, renderSelectField, renderDatePicker } from '../material-ui-wrapper';

Код:

1 — console.log(this.props) не регистрирует создателя действия — должна регистрировать функцию signupUser

'use strict';
import React, { Component } from 'react';
import { reduxForm, Field } from 'redux-form';
import * as actions from '../../actions';

import { renderTextField } from '../material-ui-wrapper';

import {Card, CardActions, CardHeader, CardText} from 'material-ui/Card';
import FlatButton from 'material-ui/FlatButton';

class Signup extends Component {
  handleFormSubmit(formProps) {
    console.log(this.props);
    this.props.signupUser(formProps);
  }

  renderAlert() {
    if (this.props.errorMessage) {
      return (
        <div className="error">
          {this.props.errorMessage}
        </div>
      );
    }
  }

  render() {
    const { handleSubmit, pristine, submitting } = this.props;
    return (
      <form id="form" onSubmit={handleSubmit(this.handleFormSubmit.bind(this))}>
        <Card>
          <CardHeader title="Cadastre-se"/>
          <CardText>
            <Field name="email" component={renderTextField} label={"Email"} fieldType="text"/>
            <Field name="password" component={renderTextField} label={"Senha"} fieldType="password"/>
            <Field name="passwordConfirm" component={renderTextField} label={"Confirmação de senha"} fieldType="password"/>
            {this.renderAlert()}
          </CardText>
          <CardActions>
            <FlatButton type="submit" label="Criar!"/>
          </CardActions>
        </Card>
      </form>
    );
  }
}

function validate(formProps) {
  const errors = {};

  if (!formProps.email || !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(formProps.email)) {
    errors.email = 'Por favor, informe um email válido';
  }

  if (formProps.password !== formProps.passwordConfirm) {
    errors.password = 'Senhas devem ser iguais.';
  }

  if (!formProps.password) {
    errors.password = 'Por favor, informe uma senha.';
  }

  if (!formProps.passwordConfirm) {
    errors.passwordConfirm = 'Por favor, confirme a sua senha.';
  }

  return errors;
}

function mapStateToProps(state) {
  return { errorMessage: state.auth.error };
}

export default reduxForm({
  form: 'signup',
  validate
}, mapStateToProps, actions)(Signup);

ИЗМЕНИТЬ

Измененный:

export default reduxForm({ form: 'signup', validate }, mapStateToProps, actions)(Signup);

To:

Signup = reduxForm({ form: 'signup', validate })(Signup); export default Signup = connect(mapStateToProps, actions)(Signup);

Это сработало. Это самый правильный способ исправить это?


person Will    schedule 10.07.2016    source источник


Ответы (4)


Вместо:

export default reduxForm({
  form: 'signup',
  validate
}, mapStateToProps, actions)(Signup);

Использовать:

Signup = reduxForm({
form: 'signup',
validate})(Signup);

export default Signup = connect(mapStateToProps, actions)(Signup);

PS: это может быть обходной путь

person Will    schedule 10.07.2016
comment
о боже... регрессия API, обратно не совместима, ужасно пахнет на расстоянии - person Igor Donin; 05.04.2017
comment
@IgorDonin OP работал через основную версию (v5 -> v6), так что это приемлемо с точки зрения semver. - person gustavohenke; 10.07.2017

Вы можете использовать композицию, например, следовать

import { compose } from 'redux'
....
export default compose(
    reduxForm({
      form: 'survey',
    }),
    connect(mapStateToProps, actions)
)(Signup)
person colorfulberry    schedule 11.07.2016
comment
Конечно должен import { connect } from 'react-redux'. - person colorfulberry; 12.07.2016

Чтобы получить эти значения в вашем компоненте, оформленном в виде редукционной формы, вам нужно будет самостоятельно подключиться() к состоянию Redux и сопоставить редьюсер данных с реквизитом initialValues.

http://redux-form.com/6.0.0-alpha.4/examples/initializeFromState/

person Diogo Cardoso    schedule 17.08.2016

Вы можете использовать конструктор для привязки метода к вашим существующим реквизитам. вам не нужно передавать действия и начальное состояние.

class Signup extends Component {

  constructor(props) {
     super(props);
     this.handleSubmit = this.handleSubmit.bind(this)
   }

   handleSubmit(formProps) {
     console.log(this.props);
     this.props.signupUser(formProps);
  }
  render() {

  const { handleSubmit, pristine, submitting } = this.props;

  return (

  <form id="form" onSubmit={this.handleFormSubmit}>
    <Card>
      <CardHeader title="Cadastre-se"/>
      <CardText>
        <Field name="email" component={renderTextField} label={"Email"} fieldType="text"/>
        <Field name="password" component={renderTextField} label={"Senha"} fieldType="password"/>
        <Field name="passwordConfirm" component={renderTextField} label={"Confirmação de senha"} fieldType="password"/>
       </CardText>
        <CardActions>
          <FlatButton type="submit" label="Criar!"/>
        </CardActions>
      </Card>
    </form>
   );
  }
 }
}
Signup = reduxForm({
 form: 'signup',
 validate})(Signup);

export default Signup = connect()(Signup);
person Jazul Kerk    schedule 30.10.2017