【问题标题】:Initializing dynamically created redux-form field初始化动态创建的 redux-form 字段
【发布时间】:2017-04-04 03:15:38
【问题描述】:

我有一个动态创建的 redux-form 字段。例如,当我点击一个按钮时,我会这样做:

renderFormFields() {
 const r = someArray.map(s => {
   console.log(s.Value);
   return (<Field name={s.Name} type='number' component='input' min='1' {...s.Value} />);
 })

 {r}
}

render() {
 renderFormFields()
}

现在console.log 正在为s.Value 打印正确的值,但 redux-form 元素没有正确的值。呈现输入字段时,值为empty。知道动态创建 redux-form 字段时我可以做些什么来初始化它吗? (我不能使用文档中提到的handleInitialize函数方法,因为表单字段是在运行时动态生成的)

【问题讨论】:

    标签: javascript forms reactjs redux-form


    【解决方案1】:

    Field 组件不包含 value 属性。您可以使用几个选项设置默认值:

    1. initialValues(如果您知道要动态添加的字段的默认值)
    2. 使用this.props.change(如果默认值也是动态的)

    来自 redux-form 的 SimpleForm 示例的修改版本:

    import React from 'react'
    import { connect } from 'react-redux'
    import { Field, reduxForm } from 'redux-form'
    
    const extendedFields = [{ name: 'City', value: 'Hyderabad' }, { name: 'Phone', value: 2 }];
    
    class SimpleForm extends React.Component {
    
      constructor() {
        super();
        this.state = {
          showExtended: false
        };
      }
    
      addExtendedFields() {
        // Not the best way to handle state. Doing this for simplicity
        this.setState({ showExtended: { initialized: false } });
      }
    
      renderExtendedFields() {
        const r = extendedFields.map(field => {
          return (
            <div key={field.name}>
              <label>{field.name}</label>
              <div>
                <Field type='text' component='input' {...field} value={field.value} />
              </div>
            </div>
          );
        });
    
        return r;
      }
    
      componentDidUpdate() {
        const { showExtended } = this.state;
        if (showExtended && !showExtended.initialized) {
          extendedFields.map(field => {
            this.props.change(field.name, field.value); // Option-2
            return field;
          });
          this.setState({ showExtended: { initialized: true } });
        }
      }
    
      render() {
        const { handleSubmit, pristine, reset, submitting } = this.props;
        const { showExtended } = this.state;
        return (
          <form onSubmit={handleSubmit}>
            <div>
              <label>First Name</label>
              <div>
                <Field name="firstName" component="input" type="text" placeholder="First Name" />
              </div>
            </div>
            <div>
              <label>Last Name</label>
              <div>
                <Field name="lastName" component="input" type="text" placeholder="Last Name" />
              </div>
            </div>
            <div>
              <label>Email</label>
              <div>
                <Field name="email" component="input" type="email" placeholder="Email" />
              </div>
            </div>
            <div>
              <label>Sex</label>
              <div>
                <label><Field name="sex" component="input" type="radio" value="male" /> Male</label>
                <label><Field name="sex" component="input" type="radio" value="female" /> Female</label>
              </div>
            </div>
            <div>
              <label>Favorite Color</label>
              <div>
                <Field name="favoriteColor" component="select">
                  <option></option>
                  <option value="ff0000">Red</option>
                  <option value="00ff00">Green</option>
                  <option value="0000ff">Blue</option>
                </Field>
              </div>
            </div>
            <div>
              <label htmlFor="employed">Employed</label>
              <div>
                <Field name="employed" id="employed" component="input" type="checkbox" />
              </div>
            </div>
            {showExtended && this.renderExtendedFields()}
            <div>
              <label>Notes</label>
              <div>
                <Field name="notes" component="textarea" />
              </div>
            </div>
            <div>
              <button type="submit" disabled={pristine || submitting}>Submit</button>
              <button type="button" disabled={pristine || submitting} onClick={reset}>Clear Values</button>
              <button type="button" onClick={this.addExtendedFields.bind(this)} disabled={showExtended}>Show Extended fields</button>
            </div>
          </form>
        );
      }
    }
    
    let HOCSimpleForm = reduxForm({
      form: 'simple'
    })(SimpleForm);
    
    HOCSimpleForm = connect(
      state => ({
        initialValues: { City: 'Test' } // Option-1
      })
    )(HOCSimpleForm)
    
    export default HOCSimpleForm;
    

    【讨论】:

      【解决方案2】:

      你不应该传播 's' 而不是 s.value 吗?

      return (<Field name={s.Name} type='number' component='input' min='1' {...s} />);
      

      【讨论】:

      • s 还包含除名称和值之外的其他字段,例如:s.Email、s.Phone 等。点差操作员如何知道该字段选择什么值?我可能应该在我的代码中使用与“Value”不同的字符串来清楚地解释。
      • 如果只想使用value,不能直接设置prop value={s.value}
      • 我确实尝试过。即使这样,初始值也是空的。我的意思是,s.value 的 console.log 显示为 1,但文本框为空。
      • 顺便说一句,扩展运算符只是扩展对象的所有属性。 developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
      【解决方案3】:

      因为你把 s 放在这样的字符串符号中 's.Name'

      你可以这样写{s.Name}

      【讨论】:

      • 名字没有问题。我得到了正确的初始名称。是的,我需要使用{s.Name}(问题中的代码错误,我会修复它)但我的问题是针对字段的初始“值”。
      猜你喜欢
      • 2023-03-11
      • 1970-01-01
      • 1970-01-01
      • 2015-07-10
      • 1970-01-01
      • 2017-10-24
      • 2017-11-18
      • 1970-01-01
      • 2011-12-07
      相关资源
      最近更新 更多