redux表单未更新选择字段

时间:2018-11-21 15:19:55

标签: reactjs redux-form

我正在使用7.2.x版,并且我已修复了onBlur的错误,该错误会重置输入的值。我现在遇到的问题是,我可以看到状态变化,并且现在它拥有正确的值,但是在gui上,它不会更改该值以显示正确的值。

在我的减速器中,我有forms: formReducer,

在我的组件类中

const mapStateToProps = state => {
    return state;
}

function mapDispatchToProps(dispatch) {
    return bindActionCreators(
        {
            change,
        },
        dispatch
    );
}

const IAMSubnetFormP = reduxForm({
    form: 'iamSubnetNewForm', // a unique name for this form
    fields: ['type_of_subnet_id', 'subnet_type', 'location', 'security_zone', 'seczone', 'routing_domain', 'zone_confirm', 'subnet_size', 'subnet_confirm', 'iam_addressing_type_id', 'address_space', 'allocation_range', 'new_subnet', 'desc_vr', 'desc_vr_confirm', 'l2env', 'l2env_confirm', 'l3dev', 'l3dev_confirm', 'zone_platform', 'wo', 'iam_network_diagram_id', 'subnet_class', 'project', 'justification', 'project_confirm']
})(IAMSubnetForm);

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

选择框显示如下

renderTypeOfSubnet() {
        let disabled = true;
        let data = this.state.data;
        console.log(this)
        if (Object.keys(this.props.forms.iamSubnetNewForm).length > 0 
                &&  'values' in this.props.forms.iamSubnetNewForm 
                && 'type_of_subnet_id' in this.props.forms.iamSubnetNewForm.values) {
            disabled = false;
        }

        return <Field 
                label="Please select the type of subnet?" 
                name="type_of_subnet_id" 
                component={this.renderSelectField} 
                type="select" disabled={disabled} data={data}
                onBlur={() => {}}
                />;
    }


renderSelectField(field) {
        const { input, label, type, meta: { touched, error, warning }, data, disabled } = field;
        let options = [];
        const className = `form-group ${touched && error ? 'has-danger' : ''}`;
        const uniqueList = [];
        const uniqueListObject = [];
        if (input.name == 'type_of_subnet_id') {
            this.state.data.map(row => {
                if (uniqueList.indexOf(row.subnet_type) === -1) {
                    uniqueList.push(row.subnet_type);
                    uniqueListObject.push({ id: row.iam_type_id, text: row.subnet_type, vlan: row.vlan });
                }
            });
            let newuniqueListObject = uniqueListObject.sort(function(a, b) {
                var nameA = a.text.toLowerCase(),
                    nameB = b.text.toLowerCase();
                if (nameA < nameB)
                    //sort string ascending
                    return -1;
                if (nameA > nameB) return 1;
                return 0; //default return value (no sorting)
            });
            options = this.populateOptionsObject(newuniqueListObject);
        } 

        let id = 'select_' + input.name;

        if (input.name == 'security_zone' && this.props.forms.iamSubnetNewForm.values.location != '') {
            if (this.props.forms.iamSubnetNewForm.values.subnet_type != 'NAT') {
                options.unshift(
                    <option key="" value="">
                        -- select --
                    </option>
                );
            } else {
                uniqueListObject.push({ id: 'E1', text: 'N/A' });
                options = this.populateOptionsObject(uniqueListObject);
            }
        } else if (input.name != 'wo' && input.name != 'iam_network_diagram_id' && input.name != 'subnet_class') {
            if (this.props.forms.iamSubnetNewForm.values.subnet_type != 'NAT') {
                options.unshift(
                    <option key="" value="">
                        -- select --
                    </option>
                );
            } else if (input.name == 'zone_platform' && this.props.forms.iamSubnetNewForm.values.l3dev_confirm == 'Yes' && this.props.forms.iamSubnetNewForm.values.subnet_type == 'NAT') {
                options.unshift(
                    <option key="N/A" value="N/A">
                        N/A
                    </option>
                );
            } else {
                options.unshift(
                    <option key="" value="">
                        -- select --
                    </option>
                );
            }
        } else if (input.name == 'subnet_class' && this.props.forms.iamSubnetNewForm.values.l3dev_confirm == 'Yes' && this.props.forms.iamSubnetNewForm.values.iam_network_diagram_id != '' && this.props.forms.iamSubnetNewForm.values.subnet_type == 'NAT') {
            options.unshift(
                <option key="N/A" value="N/A">
                    N/A
                </option>
            );
        }

        return (
            <div className={className}>
                <label className="control-label col-sm-4">{label}</label>
                <div className="col-sm-8">
                    <select
                        {...input}
                        onBlur={() => {}}
                        className="form-control form-control-inline"
                        type={type}
                        onChange={event => {

                            this.resetValues(event);
                            if (event.target.name == 'type_of_subnet_id') {
                                if (event.target.value.length > 0) {
                                    let type_of_subnet = _.find(uniqueListObject, { id: event.target.value });

                                    if (type_of_subnet.text == 'NAT') {
                                        this.props.change('security_zone', 'N/A');
                                        this.props.change('seczone', 'E1');
                                    }

                                    this.props.change('subnet_type', type_of_subnet.text);
                                    this.props.change('vlan', type_of_subnet.vlan);
                                } else {
                                    this.props.change('subnet_type', '');
                                    this.props.change('seczone', '');
                                    this.props.change('security_zone', '');
                                }
                            } 
                            this.props.change(event.target.name, event.target.value);
                        }}
                        disabled={disabled}
                    >
                        {options}
                    </select>
                </div>
                <div className="row-fluid">
                    <div className="col-sm-2" />
                    <div className="col-sm-10">
                        {touched &&
                            ((error && (
                                <span className="text-danger">
                                    <i className="fa fa-exclamation-circle" aria-hidden="true" /> {error}
                                </span>
                            )) ||
                                (warning && (
                                    <span className="text-warning">
                                        <i className="fa fa-question-circle" aria-hidden="true" /> {warning}
                                    </span>
                                )))}
                    </div>
                </div>
            </div>
        );
    }

在change事件之后,似乎没有触发重新渲染以更新from端的值。但是它在道具中拥有正确的价值

我在这里复制了问题

https://codesandbox.io/s/24x376j98n

我需要能够支持多种形式。例如表单位于不同的组件中,但呈现在同一视图上

1 个答案:

答案 0 :(得分:0)

您应该将值属性传递给“选择”标签

<select
   ...
  value={event.target.value}
  ...
/>
</select>

检查此退货单

return (
        <div className={className}>
          <label className="control-label col-sm-4">{label}</label>
          <div className="col-sm-8">
            <select
              {...input}
              onBlur={() => {
                console.log(field);
                console.log(input.value);
              }}
              className="form-control form-control-inline"
              type={type}
              value={event.target.value}
              onChange={event => {
                this.resetValues(event);
                if (event.target.name == "type_of_subnet_id") {
                  if (event.target.value.length > 0) {
                    let type_of_subnet = _.find(uniqueListObject, {
                      id: event.target.value
                    });

                    if (type_of_subnet.text == "NAT") {
                      this.props.change("security_zone", "N/A");
                      this.props.change("seczone", "E1");
                    }

                    this.props.change("subnet_type", type_of_subnet.text);
                    this.props.change("vlan", type_of_subnet.vlan);
                  } else {
                    this.props.change("subnet_type", "");
                    this.props.change("seczone", "");
                    this.props.change("security_zone", "");
                  }
                } else if (
                  event.target.name == "routing_domain" &&
                  this.props.forms.iamSubnetNewForm.values.subnet_type == "NAT" &&
                  this.props.forms.iamSubnetNewForm.values.seczone == "E1"
                ) {
                  this.props.change("zone_confirm", "Yes");
                } else if (
                  event.target.name == "security_zone" &&
                  this.props.forms.iamSubnetNewForm.values.subnet_type != "NAT" &&
                  event.target.value.length > 0
                ) {
                  let type_of_subnet = _.find(uniqueListObject, {
                    id: event.target.value
                  });

                  this.props.change("seczone", type_of_subnet.seczone);
                } else if (event.target.name == "subnet_size") {
                  if (event.target.value != "") {
                    this.props.change(
                      "iam_addressing_type_id",
                      data[0].iam_addressing_type_id
                    );

                    let self = this;
                    this.props
                      .requestSubnet(
                        data[0].iam_addressing_type_id,
                        this.props.forms.iamSubnetNewForm.values.location,
                        event.target.value,
                        this.props.forms.iamSubnetNewForm.values
                          .type_of_subnet_id,
                        this.props.forms.iamSubnetNewForm.values.security_zone,
                        this.props.forms.iamSubnetNewForm.values.routing_domain
                      )
                      .then(response => {
                        let data = response.payload.data;
                        if (data.header.error) {
                          if (
                            data.header.message ==
                            "Unable to assign a new subnet. The IP Administrator has been notified."
                          ) {
                            self.setState({
                              request_subnet: data.header.message
                            });
                          } else {
                            self.handleShowError({
                              show: true,
                              errorMsg: data.header.message
                            });
                          }
                        } else {
                          this.props.change(
                            "address_space",
                            data.body.recordset.record.address_space
                          );
                          this.props.change(
                            "allocation_range",
                            data.body.recordset.record.allocation_range
                          );
                          this.props.change(
                            "new_subnet",
                            data.body.recordset.record.new_subnet
                          );
                          self.setState({ request_subnet: "" });
                        }
                      });
                  } else {
                    this.props.change(
                      "iam_addressing_type_id",
                      data[0].iam_addressing_type_id
                    );
                  }
                } else if (event.target.name == "zone_platform") {
                  if (
                    this.props.forms.iamSubnetNewForm.values.subnet_type !=
                    "NAT" &&
                    (this.props.forms.iamSubnetNewForm.values.l3dev_confirm !=
                      "" &&
                      this.props.forms.iamSubnetNewForm.values.l3dev_confirm !=
                      "No")
                  ) {
                    this.props.fetchIAMInc().then(response => {
                      let data = response.payload.data.body.recordset.record;
                      data.map(row => {
                        if (uniqueList.indexOf(row.remedy_inc) === -1) {
                          uniqueList.push(row.remedy_inc);
                          uniqueListObject.push({
                            id: row.remedy_inc,
                            text: row.remedy_inc
                          });
                        }
                      });
                      let newuniqueListObject = uniqueListObject.sort(function (
                        a,
                        b
                      ) {
                        var nameA = a.text.toLowerCase(),
                          nameB = b.text.toLowerCase();
                        if (nameA < nameB)
                          //sort string ascending
                          return -1;
                        if (nameA > nameB) return 1;
                        return 0; //default return value (no sorting)
                      });
                      let options = this.populateOptionsObject(
                        newuniqueListObject
                      );
                      options.unshift(
                        <option key="" value="">
                          -- select --
                        </option>
                      );
                      this.setState({ wo: options });
                    });
                  }
                } else if (event.target.name == "wo") {
                  if (
                    this.props.forms.iamSubnetNewForm.values.subnet_type !=
                    "NAT" &&
                    event.target.value != ""
                  ) {
                    this.props
                      .fetchNetworkTopology(event.target.value)
                      .then(response => {
                        let data = response.payload.data.body.recordset.record;
                        data.map(row => {
                          if (uniqueList.indexOf(row.id) === -1) {
                            uniqueList.push(row.id);
                            const text = `${row.remedy_inc} v${row.version}`;
                            uniqueListObject.push({ id: row.id, text: text });
                          }
                        });
                        let newuniqueListObject = uniqueListObject.sort(function (
                          a,
                          b
                        ) {
                          var nameA = a.text.toLowerCase(),
                            nameB = b.text.toLowerCase();
                          if (nameA < nameB)
                            //sort string ascending
                            return -1;
                          if (nameA > nameB) return 1;
                          return 0; //default return value (no sorting)
                        });
                        let options = this.populateOptionsObject(
                          newuniqueListObject
                        );
                        options.unshift(
                          <option key="" value="">
                            -- select --
                          </option>
                        );
                        this.setState({ networkTopology: options });
                      });
                  } else if (
                    this.props.forms.iamSubnetNewForm.values.subnet_type ==
                    "NAT" &&
                    (this.props.forms.iamSubnetNewForm.values.l2env_confirm !=
                      "" &&
                      this.props.forms.iamSubnetNewForm.values.l2env_confirm !=
                      "No")
                  ) {
                    this.props
                      .fetchNetworkTopology(event.target.value)
                      .then(response => {
                        let data = response.payload.data.body.recordset.record;
                        data.map(row => {
                          if (uniqueList.indexOf(row.id) === -1) {
                            uniqueList.push(row.id);
                            const text = `${row.remedy_inc} v${row.version}`;
                            uniqueListObject.push({ id: row.id, text: text });
                          }
                        });
                        let newuniqueListObject = uniqueListObject.sort(function (
                          a,
                          b
                        ) {
                          var nameA = a.text.toLowerCase(),
                            nameB = b.text.toLowerCase();
                          if (nameA < nameB)
                            //sort string ascending
                            return -1;
                          if (nameA > nameB) return 1;
                          return 0; //default return value (no sorting)
                        });
                        let options = this.populateOptionsObject(
                          newuniqueListObject
                        );
                        options.unshift(
                          <option key="" value="">
                            -- select --
                          </option>
                        );
                        this.setState({ networkTopology: options });
                      });
                  }
                } else if (event.target.name == "iam_network_diagram_id") {
                  if (
                    this.props.forms.iamSubnetNewForm.values.subnet_type !=
                    "NAT" &&
                    event.target.value != ""
                  ) {
                    this.props.fetchSubnetClass().then(response => {
                      let data = response.payload.data.body.recordset.record;
                      data.map(row => {
                        if (uniqueList.indexOf(row.descriptor) === -1) {
                          uniqueList.push(row.descriptor);
                          const text = `${row.name}`;
                          uniqueListObject.push({
                            id: row.descriptor,
                            text: text
                          });
                        }
                      });
                      let newuniqueListObject = uniqueListObject.sort(function (
                        a,
                        b
                      ) {
                        var nameA = a.text.toLowerCase(),
                          nameB = b.text.toLowerCase();
                        if (nameA < nameB)
                          //sort string ascending
                          return -1;
                        if (nameA > nameB) return 1;
                        return 0; //default return value (no sorting)
                      });
                      let options = this.populateOptionsObject(
                        newuniqueListObject
                      );
                      options.unshift(
                        <option key="" value="">
                          -- select --
                        </option>
                      );
                      this.setState({ subnetClass: options });
                    });
                  } else if (
                    this.props.forms.iamSubnetNewForm.values.subnet_type ==
                    "NAT" &&
                    event.target.value != ""
                  ) {
                    let data = _.filter(this.state.data, {
                      iam_type_id: this.props.forms.iamSubnetNewForm.values
                        .type_of_subnet_id
                    });
                    data = _.filter(data, {
                      loczone: this.props.forms.iamSubnetNewForm.values.location
                    });
                    data = _.filter(data, {
                      seczone: this.props.forms.iamSubnetNewForm.values.seczone
                    });
                    data = _.filter(data, {
                      netzone: this.props.forms.iamSubnetNewForm.values
                        .routing_domain
                    });
                    let found = _.find(data, {
                      subnet_size: this.props.forms.iamSubnetNewForm.values
                        .subnet_size
                    });
                    if (found === undefined) {
                    } else {
                      this.props.change("subnet_class", "N/A");
                      this.props.change("project", "N/A");
                      this.props.change("justification", "N/A");
                      this.props.change("project_confirm", "Yes");
                      this.setState({ buttonDisabled: false });
                    }
                  }
                } else if (event.target.name == "subnet_class") {
                  if (
                    this.props.forms.iamSubnetNewForm.values.subnet_type !=
                    "NAT" &&
                    event.target.value != ""
                  ) {
                    let data = _.filter(this.state.data, {
                      iam_type_id: this.props.forms.iamSubnetNewForm.values
                        .type_of_subnet_id
                    });
                    data = _.filter(data, {
                      loczone: this.props.forms.iamSubnetNewForm.values.location
                    });
                    data = _.filter(data, {
                      seczone: this.props.forms.iamSubnetNewForm.values.seczone
                    });
                    data = _.filter(data, {
                      netzone: this.props.forms.iamSubnetNewForm.values
                        .routing_domain
                    });
                    let found = _.find(data, {
                      subnet_size: this.props.forms.iamSubnetNewForm.values
                        .subnet_size
                    });
                    if (event.target.value == "Shared" && found !== undefined) {
                      this.props.change("project", "N/A");
                      this.props.change("justification", "N/A");
                      this.props.change("project_confirm", "Yes");
                      this.setState({ buttonDisabled: false });
                    } else if (
                      event.target.value != "Shared" ||
                      found == undefined
                    ) {
                      this.setState({ buttonDisabled: true });
                    }
                  }
                }
                this.props.change(event.target.name, event.target.value);
                input.onChange(event);
                this.setState(prevState => ({
                  rerender: !prevState.rerender
                }));
                console.log("need to rerender");
              }}
              disabled={disabled}
            >
              {options}
            </select>
          </div>
          <div className="row-fluid">
            <div className="col-sm-2" />
            <div className="col-sm-10">
              {touched &&
                ((error && (
                  <span className="text-danger">
                    <i className="fa fa-exclamation-circle" aria-hidden="true" />{" "}
                    {error}
                  </span>
                )) ||
                  (warning && (
                    <span className="text-warning">
                      <i className="fa fa-question-circle" aria-hidden="true" />{" "}
                      {warning}
                    </span>
                  )))}
            </div>
          </div>
        </div>
      );