Программное изменение значения FieldArray в Redux-Form

Я пытаюсь понять, как использовать this.props.dispatch(change), чтобы использовать одно значение селектора поля для обновления значения другого поля в FieldArray.

https://codesandbox.io/s/2p7k7jn930

Кажется, я не могу понять синтаксис в этом правильно.

this.props.dispatch(
        change("FieldArraysForm", `${props.member}.firstName`, this.props.hasLastName)
      );

есть идеи? Ожидаемым поведением будет добавление члена, а затем все, что введено в поле «Фамилия», будет программным образом обновлено в поле «Имя».

/**
The following can replace the file in the Field Arrays example
(https://github.com/erikras/redux-form/tree/master/examples/fieldArrays) to demonstrate this functionality.
**/
import React from "react";
import { connect } from "react-redux";
import {
  Field,
  FieldArray,
  reduxForm,
  formValueSelector,
  change
} from "redux-form";
import validate from "./validate";

const selector = formValueSelector("fieldArrays");

const renderField = ({ input, label, type, meta: { touched, error } }) => (
  <div>
    <label>{label}</label>
    <div>
      <input {...input} type={type} placeholder={label} />
      {touched && error && <span>{error}</span>}
    </div>
  </div>
);

class Member extends React.Component {
  componentDidUpdate(prevProps, props) {
    if (this.props.hasLastName !== prevProps.hasLastName) {
      this.props.dispatch(
        change("FieldArraysForm", `${props.member}.firstName`, this.props.hasLastName)
      );
    }
  }

  render() {
    const { member, index, fields, hasLastName } = this.props;
    return (
      <li key={index}>
        <button
          type="button"
          title="Remove Member"
          onClick={() => fields.remove(index)}
        />
        <h4>Member #{index + 1}</h4>
        <Field
          name={`${member}.firstName`}
          type="text"
          component={renderField}
          label="First Name"
        />
        <Field
          name={`${member}.lastName`}
          type="text"
          component={renderField}
          label="Last Name"
        />
        {hasLastName && <p>{hasLastName}</p>}
      </li>
    );
  }
}
Member = connect((state, props) => ({
  hasLastName: selector(state, `${props.member}.lastName`)
}))(Member);

const renderMembers = ({ fields, meta: { touched, error } }) => (
  <ul>
    <li>
      <button type="button" onClick={() => fields.push({})}>
        Add Member
      </button>
      {touched && error && <span>{error}</span>}
    </li>
    {fields.map((member, index) => (
      <Member member={member} fields={fields} index={index} key={index} />
    ))}
  </ul>
);

const FieldArraysForm = props => {
  const { handleSubmit, pristine, reset, submitting } = props;
  return (
    <form onSubmit={handleSubmit}>
      <Field
        name="clubName"
        type="text"
        component={renderField}
        label="Club Name"
      />
      <FieldArray name="members" component={renderMembers} />
      <div>
        <button type="submit" disabled={submitting}>
          Submit
        </button>
        <button type="button" disabled={pristine || submitting} onClick={reset}>
          Clear Values
        </button>
      </div>
    </form>
  );
};

export default reduxForm({
  form: "fieldArrays", // a unique identifier for this form
  validate
})(FieldArraysForm);

person Shawn Matthews    schedule 04.04.2018    source источник


Ответы (2)


Чтобы получить динамический доступ к FieldArray, вы хотели бы изменить это:

change("FieldArraysForm", `${props.member}.firstName`, this.props.hasLastName)

к этому:

change("FieldArraysForm", `members[${this.props.index}].firstName`, this.props.hasLastName)

Также передайте в форме selector указанное:

const selector = formValueSelector("fieldArrays");

Это даст вам:

change("fieldArrays", `members[${this.props.index}].firstName`, this.props.hasLastName)

Пришлось получить некоторую помощь в этом - спасибо @Amanda Field.

person RNA_Polymerase    schedule 06.04.2018

Вам нужно указать индекс поля в FieldArray, которое вы хотите изменить. Для этого просто используйте <fieldName>.<index>.<propertyName>, например:

this.props.change('members.0.firstName', 'Donald')

где member — это имя вашего поля FieldArray, 0 — это индекс элемента в массиве, который вы хотите изменить, а firstName — это свойство объекта. См. песочницу здесь

person Dario    schedule 04.04.2018
comment
Спасибо за ответ! Извините, я должен был упомянуть, что я уже смог заставить его работать, жестко закодировав значение. Мне интересно, как сделать его динамическим.... Итак, если, например, создано 4 массива полей, как бы я мог динамически обрабатывать селекторы и соответственно добавлять отправки изменений. - person Shawn Matthews; 05.04.2018
comment
Есть какие-нибудь мысли об этом @Dario прямо сейчас, это стало для нас чем-то вроде остановки шоу? - person Shawn Matthews; 05.04.2018