Redux表单 - 如何处理异步选择字段的默认选择?

时间:2018-04-02 05:53:18

标签: javascript reactjs redux react-redux redux-form

我有3个组件:UserProfile,CountryControl和StateControl。我有它设置所以CountryControl和StateControl负责发出他们自己的ajax数据请求(通过动作)。当国家发生变化时,应该提取国家。 UserProfile将回调传递给CountryControl,因此我可以告诉各国在Country更改时更新。

现在这可行,但依赖于Country选择输入的onChange事件来确定何时加载状态。除了使用现有UserProfile的初始加载之外,这很好。由于当Redux Form向Field组件注入初始值时没有触发onChange事件,因此在更改Country并更改之前,我没有状态列表。

有没有办法在Redux设置表单值时触发onChange事件 - 或者可能在加载国家/地区时触发onChange?

父UserProfile组件:

class UserProfile extends Component {
  componentDidMount() {
    service.getUserIdentity(userId, (userProfile) => {
      this.props.initialize(userProfile);
    });

  onCountryChanged(e, input) {
    // dispatch a call to update states when selection changes
    input.onChange(e);
    this.props.dispatch(getStates(e.target.value));
  }

  render() {
    <div>
      <Field
          id = "name"
          label = "Name"
          placeholder = "John Doe"
          name = "name"
          component={this.renderField}
        />
        <StateControl />
        <CountryControl onSelectChanged={this.onCountryChanged} />
    </div>
  }

  renderField(field) {
    return (
      <div className="control-group">
        <div className="control-label">{field.label}</div>
        <div className="controls">
          <input {...field.input} type={field.type} placeholder={field.placeholder} className="form-control"/>
        </div>
      </div>
    );
  }
}

function mapStateToProps(state, ownProps) {
  return { userProfile: state.userProfile };
}

export default reduxForm({
  validate: validate,
  form: 'UserProfile'
})(
  connect(mapStateToProps, null)(UserProfile)
);

儿童国家控制:

class CountryControl extends Component {
  componentDidMount() {
    this.props.getCountries();
  }

  render() {
    const { countries } = this.props;
    return (
      <Field
          label = "Country"
          name = "country"
          component = {this.renderSelect}
          data = {countries}
          onCustomChange = {this.props.onSelectChanged.bind(this)}
      >
      </Field>
    );
  }

  renderSelect(field) {
    return (
      <div className="control-group">
        <div className="control-label">{field.label}</div>
        <div className="controls">
          <select 
            className="form-control"
            onChange={e => {field.onCustomChange(e, field.input) }}
            value={field.input.value}
           >
            <option value=""></option>
            {Array.isArray(field.data) ? field.data.map(option =>
              <option 
                value={option.countryCode} 
                key={option.countryCode}>{option.name}</option>) : ''}
          </select>
        </div>
      </div>
    );
  }
}

function mapStateToProps(state, ownProps) {
  return { countries: state.countries };
}

export default reduxForm({
  form: 'UserProfile'
})(
  connect(mapStateToProps, { getCountries })(CountryControl)
);

2 个答案:

答案 0 :(得分:0)

我有一些有用的东西,但我敢打赌,这是一个更好的方法。 在CountryControl中,我可以在getCountries ajax调用完成后在选择框上手动触发更改事件。

componentDidMount() {
  // load data and bind
  this.props.getCountries().then(() => {
    // trigger the onChange event
    var element = document.getElementsByName('country')[0];
    if ("createEvent" in document) {
      var evt = document.createEvent("HTMLEvents");
      evt.initEvent("change", true, true);
      element.dispatchEvent(evt);
    }
    else{
      element.fireEvent("onchange");
    }
  });
}

答案 1 :(得分:0)

我倾向于将<UserProfile />包装在挂载的组件中,获取初始值。

使用这种方法,您甚至可以获取用户=&gt; country =&gt;甚至渲染之前都需要状态信息,因此您不需要手动触发onChange。