如果使用componentDidMount / setState,则未定义Formik <fieldarray> initialValue

时间:2019-03-24 20:13:31

标签: reactjs formik

我以前从未使用过Formik,但是在网上听到一些积极的声音,这听起来比起自己动手做这是一个很棒的解决方案……我通常会尝试这样做。

Formik的文档具有其某些属性的简单实例,例如initialValuesvalidationSchema。但是,我需要使其可重用,因为我的应用程序中有2个版本。所以我想将字段作为道具传递,然后将initialValues创建为一种状态。可以,是吗?

但是,没有任何东西呈现出来……文档中显示的value, errors参数始终显示为undefined。为什么是这样?状态已更新,因此,我假设initialValues将更新values对象。 render方法内的作用域不允许我使用this.state.initial例如... 错误对象仍未定义,但我认为它至少应该存在?

基本上,我有一个Parent组件正在分发内部组件,其中之一是表单组。因此,我将字段数组和一个架构对象传递给Formik组件的容器,如下所示:

const newCompanyFields = ["name", "address", "revenue", "phone"];

<Card
  headerText="Create New Company"
  id="new-company"
  renderWith={() => (
    <React.Fragment>
      <div className="header">Add Company</div>
      <Forms fields={newCompanyFields} schema={NewCompanySchema} />
    </React.Fragment>
  )}
/>

然后,在<Forms>组件内部,我们将像下面这样创建Formik实例:

class Forms extends Component {
  state = {
    initial: {}
  };

  componentDidMount() {
    //  we need to get the list of fields and setState to be used by Formik below
    if (this.props.fields) {
      let initialItems = {};
      this.props.fields.forEach(item => {
        return (initialItems[item] = "");
      });

      this.setState({ initial: initialItems });
    }
  }

  render() {
    return (
      <StyledForms>
        <Formik
      initialValues={this.state.initial}
      validationSchema={this.props.schema}
      onSubmit={values => {
        console.log(values, " submitted");
      }}
      render={({
        values,
        errors,
        touched,
        handleBlur,
        handleChange,
        handleSubmit,
        isSubmitting
      }) => (
        <Form>
          <FieldArray
            name="field-company"
            render={() => (
              <div>
                {values &&
                  Object.keys(values).map((field, index) => (
                    <div key={index}>
                      <Field name={field} />
                      {errors[field] && touched[field] ? (
                        <div>{errors[field]}</div>
                      ) : null}
                    </div>
                  ))}
                <button type="submit" disabled={isSubmitting}>
                  Submit
                </button>
              </div>
            )}
          />
        </Form>
      )}
    />
   </StyledForms>
    );
  }

链接到控制台屏幕截图:https://screencast.com/t/Pt7YOxU1Oq57

感谢您的澄清。

更新 如果我将initialValues属性更新为不依赖组件状态,那么它将起作用。

// assume ComponentDidMount from above is removed now
const getInitialValues = passedFields => {
  let initialItems = {};
  passedFields.forEach(item => {
    return (initialItems[item] = "");
  });
  return initialItems;
};

<Formik
          initialValues={getInitialValues(this.props.fields)}
...
/>

这是预期的吗?

1 个答案:

答案 0 :(得分:0)

您需要在render()组件中使用Formik

类似的东西:

<Formik render={({ values }) => {
  <Form>
    <FieldArray>
      ... use values
    </FieldArray>
  </Form>
}} />