如何在React.js中使用Formik修复Submit form Error

时间:2019-05-07 15:16:43

标签: reactjs field formik

试图在Reactjs中显示基于Formik的动态表单,但是当我尝试提交时没有错误,并且没有任何提交。

尽管我确实收到警告说:

一个组件正在更改要控制的文本类型的不受控制的输入。输入元素不应从不受控制切换为受控制(反之亦然)。在组件的使用寿命中决定使用受控还是不受控制的输入元素

这是我的组件DynamicForm,具有表单的所有行为。

class DynamicForm1 extends Component {
  renderCheckBox(input) {
    return (
      <Fragment key={input.name}>
        <label>{input.label}</label>
        <Field
          name={input.name}
          render={(prop) => {
            const { field } = prop;
            return (
              <input
                name={input.name}
                type="checkbox"
                checked={field.value}
                onChange={field.onChange} />
            );
          }}
        />
      </Fragment>

    );
  }

  renderTextArea(input) {
    return (
      <Fragment key={input.name}>
        <label>{input.label}</label>
        <div>
          <Field
            name={input.name}
            render={(props) => {
              const { field } = props;
              const { errors, touched } = props.form;
              const hasError = errors[input.name] && touched[input.name] ? 'hasError' : '';
              return (
                <div>
                  <textarea {...field} id={hasError}>
                  </textarea>
                </div>
              );
            }}
          />
        </div>
      </Fragment>
    );
  }

  renderSelect(input) {
    return (
      <Fragment key={input.name}>
        <label>{input.label}</label>
        <div>
          <Field
            name={input.name}
            render={(props) => {
              const { field } = props;
              const { errors, touched } = props.form;
              const hasError = errors[input.name] && touched[input.name] ? 'hasError' : '';
              const defaultOption = <option key='default' value='Please Select'>Please Select</option>;
              const options = input.data.map(i => <option key={i} value={i}> {i} </option> );
              const selectOptions = [defaultOption, ...options];
              return (
                <div className='dropdown'>
                  <select value={field.value} {...field} id={hasError}>
                    {
                      selectOptions
                    }
                  </select>
                </div>
              );
            }}
          />
        </div>
      </Fragment>
    );
  }


  renderFields(inputs) {
    return inputs.map(input => {
      if(input.type === 'select') {
        return this.renderSelect(input);
      }

      if(input.type === 'checkbox') {
        return this.renderCheckBox(input);
      }

      if(input.type === 'textarea') {
        return this.renderTextArea(input);
      }
      return (

        <div key={input.name}>
          <label>{input.label}</label>
          <div>
            <Field
              name={input.name}
              render={(props) => {
                const { field } = props;
                const { errors, touched } = props.form;
                const hasError = errors[input.name] && touched[input.name] ? 'hasError' : '';
                return (
                  <input
                    {...field}
                    id={hasError}
                    type='text'

                  />
                );
              }}
            />
          </div>
        </div>
      );
    })
  }

  getInitialValues(inputs) {
    //declare an empty initialValues object
    const initialValues = {};
    //loop loop over fields array
    //if prop does not exit in the initialValues object,
    // pluck off the name and value props and add it to the initialValues object;
    inputs.forEach(field => {
      if(!initialValues[field.name]) {
        initialValues[field.name] = field.value;
      }
    });

    //return initialValues object
    console.log(" initial values1" + initialValues);
    return initialValues;
  }

  render() {
    const initialValues = this.getInitialValues(this.props.fields);
    console.log(" initial values2" + JSON.stringify(initialValues));
    return (
      <div className="app">
        <h1>Dynamic Form</h1>
        <Formik
          onSubmit={(values) => {console.log("values :" +JSON.stringify(values))}}
          validationSchema={this.props.validation}
          initialValues={initialValues}
          render={(form) => {
            const errorMessageShow = Object.keys(form.errors).length > 0 ? 'error' : 'hidden';
            return <div>
              <form onSubmit={form.handleSubmit} onChange={form.handleChange}>
                <div className={errorMessageShow}>
                  Please correct the errors below
                </div>
                {this.renderFields(this.props.fields)}

                <button type='submit' className='btn'>Submit</button>
              </form>
            </div>
          }}
        />
      </div>
    );
  }
}


export default DynamicForm1;

然后是App.js,其中包含我从API收集的数据并将其推送到DynamicForm。

class App3 extends Component {
  constructor(props){
    super(props);
  this.state={
    fields:[]

  };
  this.getData = this.getData.bind(this);
  }
  getData(){
    axios.get(`http://localhost:3006/formulaire`)
    .then(res => {
      this.setState({
        fields: res.data
      })
    })
  }
  componentDidMount() {
    this.getData();

  }
  render() {
    return (
     <DynamicForm1 fields={this.state.fields} validation={validation} />
    )
  }
}
export default App3;

0 个答案:

没有答案