Reactjs + Redux Form FieldArray条件渲染

时间:2018-11-21 12:39:06

标签: reactjs forms redux redux-form

我对ReactJS和Redux很陌生。我正在尝试使用reactjs和redux-form实现复杂的动态形式。短篇小说:

我需要动态生成允许具有多种类型的多个答案的表格。谷歌如何运作的更多或更少。

基本上,用户可以创建自己的表格/问卷。示例:

您去过纽约吗? (广播->是/现在)

如果用户单击“是”,则呈现另一个问题集:

您花了多少时间参观? (复选框输入:1-2小时,2-4小时,4-6小时)

如果用户单击“ 4-6hours”,则提出另一个问题:

哇!您能告诉我们您在哪里花了那么多时间吗? (文本输入答案)

以此类推。当然,这只是一个基本示例,表单甚至比这还要复杂。

现在,进入代码。我最初的方法是使用FieldArray。看起来是这样:

  <FieldArray 
    name="question" 
    component={renderMultipleCheckboxes} 
    options={[{id:1,value:true,label:'a'},{id:2,value:true,label:'b'}]}
    allowAnswer={true}
    allowAnswerForValue={[2]}
    allowAnswerFieldName="question_answer"
    allowAnswerFieldLabel="Your answer"
  />

此FieldArray是导出为以下大格式的一部分:

Form.propTypes = {
  user: PropTypes.object.isRequired
}

Form = reduxForm({
  form: 'form_x',
})(Form);

Form = connect(state => ({
  account: state.account,
}))(Form);

export default Form;

renderMultipleCheckboxes组件:

export class renderMultipleCheckboxes extends React.PureComponent {

  render() {
    const {   
      input,
      fields, 
      options, 
      meta: { error, submitFailed }, 
      allowAnswer,
      allowAnswerForValue,
      allowAnswerFieldName,
      allowAnswerFieldLabel 
    } = this.props;

    return fields.map((item, index) => { 

      let option = options.map((item) => {
        if (item.id === index) {
          return item;
        }
      })

      // What would be the approach to show answer input ? This line of code works only once.  
      let showAnswerField = document.getElementsByName(item)[0].checked && allowAnswer && allowAnswerForValue.indexOf(index) > -1;

      return (
        <React.Fragment>
          <Field
            label={option[index].label}
            name={`${item}`}
            component={renderCheckBoxField}
            key={index}
          />
          {showAnswerField &&
            <Field
              label={allowAnswerFieldLabel}
              name={allowAnswerFieldName}
              component={'input'}
              key={index + 1}
            />
          }
        </React.Fragment>
      )
    })
  }
}

renderCheckBoxField组件:

class CheckBoxField extends PureComponent {
  componentDidMount() {
    this.props.onChange(this.props.defaultChecked);
  }

  render() {
    const disabled = this.props.disabled;

    return (
      <label
        className={`checkbox-btn${disabled ? ' disabled' : ''}${this.props.class ? ` checkbox-btn--${this.props.class}` : ''}`}>
        <input className='checkbox-btn__checkbox'
               type='checkbox' name={this.props.name} onChange={this.props.onChange}
               checked={this.props.value} disabled={disabled}/>
        <span className='checkbox-btn__checkbox-custom'
              style={this.props.color ? {background: this.props.color, borderColor: this.props.color} : {}}>
            <CheckIcon/>
          </span>
        {this.props.class === 'button' ?
          <span className='checkbox-btn__label-svg'>
              <CheckIcon className='checkbox-btn__label-check'/>
              <CloseIcon className='checkbox-btn__label-uncheck'/>
            </span> : ''}
        <span className='checkbox-btn__label'>
          {this.props.label}
          </span>
      </label>
    )
  }
}

const renderCheckBoxField = (props) => {
  let label = props.label;
  return (
  <CheckBoxField
    {...props.input}
    label={label}
    defaultChecked={props.defaultChecked}
    disabled={props.disabled}
    class={props.class}
    color={props.color}
  />
)};

renderCheckBoxField.propTypes = {
  input: PropTypes.object.isRequired,
  label: PropTypes.string,
  defaultChecked: PropTypes.bool,
  disabled: PropTypes.bool,
  class: PropTypes.string,
  color: PropTypes.string
};

export default renderCheckBoxField;

我不确定我对自己的解释是否足够好。

重要提示:我不能使用formValues,因为表单字段是动态生成的。或者至少我不知道如何实现这一目标。

0 个答案:

没有答案