使用字段数组进行React,Formik,可重复表单字段

时间:2019-10-21 22:13:42

标签: javascript reactjs formik

我试图弄清楚如何将React与Formik的字段数组一起使用,以将可重复的表单组件嵌入到我的表单中。

我有一个正在运行的系统(我认为)。它是来自10多个来源的建议的组合,所以我开始认为我已经离开了种植园,因为必须有一种明显的方法来进行设置(但我无法弄清楚)。

此刻,我当前的方法正在生成警告:

  

一个组件正在将文本类型的不受控制的输入更改为   受控。输入元素不应从不受控制的切换到   控制(反之亦然)。决定使用受控还是   组件生命周期中不受控制的输入元素。更多   信息:https://reactjs.org/docs/forms.html#controlled-components

我的代码沙箱在这里:https://codesandbox.io/s/goofy-glade-lx65p?from-embed。对于那些不想使用此工具的人,沙盒中的代码粘贴在这篇文章的底部。

您可以看到可以渲染和删除可重复嵌入的表单。但是,嵌入的窗体有一个错误,指出:this.props.formik.registerField不是函数。 (在“ this.props.formik.registerField(this.props.name,this)”中,“ this.props.formik.registerField”未定义)

我不知道这意味着什么。我不在任何地方使用称为registerField的东西。我应该吗?我已经看到this post描述了如何设置初始状态来解决此警告,但是如果我在请求表单中进行设置,则会在主表单上显示一个空白表单(我不希望那样,我会只希望链接嵌入一个)。

任何人都可以看到我对国家的错吗?

表格:

import React from "react";
import { Link } from "react-router-dom";
import {
  Formik,
  Form,
  Field,
  FieldArray,
  ErrorMessage,
  withFormik
} from "formik";
// import * as Yup from "yup";
import Select from "react-select";
// import { fsDB, firebase, settings } from "../../../firebase";
import Requests from "./Requests";

import {
  Badge,
  Button,
  Col,
  ComponentClass,
  Feedback,
  FormControl,
  FormGroup,
  FormLabel,
  InputGroup,
  Table,
  Row,
  Container
} from "react-bootstrap";

const style2 = {
  paddingTop: "2em"
};

const initialValues = {
  title: "",
  Requests: [],
  createdAt: ""
};

class MainForm extends React.Component {
  state = {
    options: []
  };

  async componentDidMount() {
    // const fsDB = firebase.firestore(); // Don't worry about this line if it comes from your config.
    let options = [];
    // await fsDB.collection("abs_for_codes").get().then(function (querySnapshot) {
    // querySnapshot.forEach(function(doc) {
    //     console.log(doc.id, ' => ', doc.data());
    //     options.push({
    //         value: doc.data().title.replace(/( )/g, ''),
    //         label: doc.data().title + ' - ABS ' + doc.id
    //     });
    //     });
    // });
    this.setState({
      options
    });
  }

  handleSubmit = (formState, { resetForm }) => {
    // Now, you're getting form state here!
    const payload = {
      ...formState,
      createdAt: firebase.firestore.FieldValue.serverTimestamp()
    };
    console.log("formvalues", payload);

    // fsDB
    //   .collection("project")
    //   .add(payload)
    //   .then(docRef => {
    //     console.log("docRef>>>", docRef);
    //     resetForm(initialValues);
    //   })
    //   .catch(error => {
    //     console.error("Error adding document: ", error);
    //   });
  };

  render() {
    const { options } = this.state;

    return (
      <Formik
        initialValues={initialValues}
        onSubmit={this.handleSubmit}
        render={({
          errors,
          status,
          touched,
          setFieldValue,
          setFieldTouched,
          handleSubmit,
          isSubmitting,
          dirty,
          values,
          arrayHelers
        }) => {
          return (
            <div>
              <Form>
                <Table responsive>
                  <thead>
                    <tr>
                      <th>#</th>
                      <th>Element</th>
                      <th>Insights</th>
                    </tr>
                  </thead>
                </Table>
                {/*General*/}
                <h5 className="formheading">general</h5>
                <Table responsive>
                  <tbody>
                    <tr>
                      <td>1</td>
                      <td>
                        <div className="form-group">
                          <label htmlFor="title">Title</label>
                          <Field
                            name="title"
                            type="text"
                            className={
                              "form-control" +
                              (errors.title && touched.title
                                ? " is-invalid"
                                : "")
                            }
                          />
                          <ErrorMessage
                            name="title"
                            component="div"
                            className="invalid-feedback"
                          />
                        </div>
                      </td>
                      <td className="forminsight">No insights</td>
                    </tr>
                  </tbody>
                </Table>
                {/*Method*/}
                {/* <SoPTip /> */}

                {/*Resources s*/}
                <Table responsive>
                  <tbody>
                    <tr>
                      <td>
                        <label htmlFor="Requests">Request</label>

                        <FieldArray
                          name="Requests"
                          render={arrayHelpers => (
                            <React.Fragment>
                              {values.Requests.map((funding, i) => (
                                <Requests
                                  setFieldValue={setFieldValue}
                                  arrayHelpers={arrayHelpers}
                                  values={values}
                                  data={funding}
                                  key={i}
                                  index={i}
                                />
                              ))}
                              <div>
                                <Button
                                  variant="link"
                                  size="sm"
                                  onClick={() =>
                                    arrayHelpers.push({
                                      title: "",
                                      description: "",
                                      source: "",
                                      disclosure: "",
                                      conflicts: ""
                                    })
                                  }
                                >
                                  Add request
                                </Button>
                              </div>
                            </React.Fragment>
                          )}
                        />
                      </td>
                      <td className="forminsight">No insights</td>
                    </tr>
                  </tbody>
                </Table>
                <div className="form-group">
                  <Button
                    variant="outline-primary"
                    type="submit"
                    id="ProjectId"
                    onClick={handleSubmit}
                    disabled={!dirty || isSubmitting}
                    onSubmit={values => console.log(values)}
                  >
                    Save
                  </Button>
                </div>
              </Form>
            </div>
          );
        }}
      />
    );
  }
}

export default MainForm;

请求可重复形式:

import React from "react";
import { Field } from "formik";
import Select from "react-select";

import { Table, Button } from "react-bootstrap";

const Currencies = [
  { value: "usd", label: "United States Dollars (USD)" },
  { value: "nzd", label: "New Zealnd Dollars (NZD)" },
  { value: "gbp", label: "Pounds Sterling (GBP)" },
  { value: "cad", label: "Canadian Dollars (CAD)" }
];

class Requests extends React.Component {
  render() {
    const {
      index,
      values,
      setFieldValue,
      setFieldTouched,
      arrayHelpers,
      remove
    } = this.props;

    return (
      <div>
        <Table responsive>
          <tbody>
            <tr>
              <td>
                <div className="form-group">
                  <label htmlFor="RequestsTitle">Title</label>

                  <Field
                    name={`Requests.${index}.title`}
                    placeholder="Add a title"
                    className="form-control"
                  />
                </div>
              </td>
            </tr>
            <tr>
              <td>
                <div className="form-group">
                  <label htmlFor="RequestsSource">Source</label>
                  <Field
                    name={`Requests.${index}.source`}
                    component="textarea"
                    rows="10"
                    placeholder="Leave blank and skip ahead if you don't"
                    className="form-control"
                  />
                </div>
              </td>
            </tr>
            <tr>
              <td>
                <div className="form-group">
                  <label htmlFor="Currency">Select your currency</label>

                  <Select
                    key={`my_unique_select_keyCurrency`}
                    name={`Requests.${index}.Currency`}
                    className={"react-select-container"}
                    classNamePrefix="react-select"
                    onChange={({ value: selectedOption }) => {
                      console.log(selectedOption);
                      setFieldValue(
                        `Requests.${index}.Currencies`,
                        selectedOption
                      );
                    }}
                    onBlur={setFieldTouched}
                    options={Currencies}
                  />
                </div>
              </td>
              <td className="forminsight">No insights</td>
            </tr>
            <tr>
              <td>
                <div className="form-group">
                  <label htmlFor="RequestsAmount">
                    What amount of funding are you seeking?
                  </label>
                  <Field
                    name={`Requests.${index}.amount`}
                    type="text"
                    placeholder="Enter a number without a currency symbol"
                    className={"form-control"}
                  />
                </div>
              </td>
              <td className="forminsight">No insights</td>
            </tr>
            <tr>
              <td>
                <div className="form-group">
                  <label htmlFor="RequestsDisclosure">Disclosure</label>
                  <Field
                    name={`Requests.${index}.disclosure`}
                    component="textarea"
                    rows="10"
                    placeholder="Consider."
                    className="form-control"
                  />
                </div>
              </td>
            </tr>
            <tr>
              <td>
                <div className="form-group">
                  <label htmlFor="RequetsConflicts">Conflicts</label>
                  <Field
                    name={`Requests.${index}.conflicts`}
                    component="textarea"
                    rows="10"
                    placeholder="Take a look at the checklist. "
                    className="form-control"
                  />
                </div>
              </td>
              <td className="forminsight">No insights</td>
            </tr>
            <tr>
              <td>
                <div className="form-group">
                  <label htmlFor="RequestsBudget">
                    Do you have a budget for how this funding will be deployed?
                  </label>
                  <Field
                    name={`Requests.${index}.budget`}
                    component="textarea"
                    rows="10"
                    placeholder="Leave blank if you don't."
                    className="form-control"
                  />
                </div>
              </td>
              <td className="forminsight">No insights</td>
            </tr>
          </tbody>
        </Table>
        <Button
          variant="outline-secondary"
          size="sm"
          onClick={() => arrayHelpers.remove(index)}
        >
          Remove this request
        </Button>
      </div>
    );
  }
}

export default Requests;

1 个答案:

答案 0 :(得分:0)

我发现该警告的原因是您的Requests中有initialValues,但是您在表单中使用了fundingRequests
当我改变

<Field
  name={`fundingRequests.${index}.title`}
  placeholder="Add a title"
  className="form-control"
 />

 <Field
   name={`Requests.${index}.title`}
   placeholder="Add a title"
   className="form-control"
 />

将不再有警告。 让我知道这是否不能解决问题