如何在Reactjs中使用formik修复提交表单错误

如何在Reactjs中使用formik修复提交表单错误,reactjs,field,formik,Reactjs,Field,Formik,尝试在Reactjs中显示基于Formik的动态表单,但当我尝试提交时没有错误,也没有提交任何内容 虽然我确实收到了警告,说: 组件正在更改要控制的文本类型的非受控输入。输入元件不应从非受控切换到受控(反之亦然)。决定在组件的使用寿命内使用受控或非受控输入元件 这是我的组件DynamicForm,它包含表单的所有行为 class DynamicForm1 extends Component { renderCheckBox(input) { return ( <Fr

尝试在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;
类DynamicForm1扩展组件{
renderCheckBox(输入){
返回(
{input.label}
{
常量{field}=prop;
返回(
);
}}
/>
);
}
RenderExtArea(输入){
返回(
{input.label}
{
常量{field}=props;
const{errors,toucted}=props.form;
const hasError=errors[input.name]&&toucted[input.name]?'hasError':'';
返回(
);
}}
/>
);
}
渲染选择(输入){
返回(
{input.label}
{
常量{field}=props;
const{errors,toucted}=props.form;
const hasError=errors[input.name]&&toucted[input.name]?'hasError':'';
const defaultOption=请选择;
const options=input.data.map(i=>{i});
const selectOptions=[defaultOption,…options];
返回(
{
选择选项
}
);
}}
/>
);
}
渲染场(输入){
返回inputs.map(输入=>{
如果(input.type==='select'){
返回此.renderSelect(输入);
}
如果(input.type==='复选框'){
返回此.renderCheckBox(输入);
}
if(input.type==='textarea'){
返回此.renderTextArea(输入);
}
返回(
{input.label}
{
常量{field}=props;
const{errors,toucted}=props.form;
const hasError=errors[input.name]&&toucted[input.name]?'hasError':'';
返回(
);
}}
/>
);
})
}
getInitialValues(输入){
//声明一个空的initialValues对象
常量initialValues={};
//域上循环数组
//如果prop在initialValues对象中不存在,
//去掉名称和值道具并将其添加到initialValues对象中;
inputs.forEach(字段=>{
如果(!initialValues[field.name]){
initialValues[field.name]=field.value;
}
});
//返回初始值对象
console.log(“初始值1”+初始值);
返回初始值;
}
render(){
const initialValues=this.getInitialValues(this.props.fields);
log(“initialvalues2”+JSON.stringify(initialValues));
返回(
动态形式
{console.log(“值:+JSON.stringify(值))}
validationSchema={this.props.validation}
initialValues={initialValues}
呈现={(形式)=>{
const errorMessageShow=Object.keys(form.errors).length>0?'error':'hidden';
返回
请更正下面的错误
{this.renderFields(this.props.fields)}
提交
}}
/>
);
}
}
导出默认动态FORM1;
还有一个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;
类App3扩展组件{
建造师(道具){
超级(道具);
这个州={
字段:[]
};
this.getData=this.getData.bind(this);
}
getData(){
axios.get(`http://localhost:3006/formulaire`)
。然后(res=>{
这是我的国家({
字段:res.data
})
})
}
componentDidMount(){
这是getData();
}
render(){
返回(
)
}
}
导出默认App3;

您能提供一个codesandbox吗?如果值的初始化不正确,通常会发生非受控到受控的错误。初始化值的输出是什么?能否提供代码沙盒?如果值的初始化不正确,通常会发生非受控到受控的错误。初始化值的输出是什么?