简体   繁体   English

如何从与其他字段的formik形式反应FieldArray中获取值?

[英]How to get values from react FieldArray in formik form with other fields?

I have created a Formik form that contains a field array, form and fieldArray is in two separate classes as separate components.我创建了一个包含字段数组的 Formik 表单,表单和fieldArray位于两个单独的类中,作为单独的组件。

My form:我的表格:

<Formik onSubmit = {(values, { setSubmitting }) => { setSubmitting(false);}}
        enableReinitialize>
    {({handleSubmit, errors})=> (
        <Form onSubmit= { handleSubmit }>
            <Form.Group as= { Row } controlId= "cpFormGroupTitle" className="required">
                <Form.Label className="post-create-label"  column sm={ 2 } >
                    Title
                </Form.Label>
                <Col sm={ 10 }>
                    <Field name="title" component={ renderTextField } type="text"
                           isinvalid={ !!errors.title ? "true": "false" }
                           placeholder="Title *" />
                </Col>
            </Form.Group>
            <Form.Group as= { Row } controlId= "cpFrmGroupShortDesc"  className="required">
                <Form.Label className="post-create-label"  column sm={ 2 } >
                    Short Description
                </Form.Label>
                <Col sm={ 10 }>
                    <Field name="short-desc" component={ renderTextArea } type="text"
                           isinvalid={ !!errors.shortDescription ? "true": "false" }
                           placeholder="Short Description *" />
                </Col>
            </Form.Group>
            <Form.Group as= { Row } controlId= "cpFormGroupFeatures">
                <Form.Label className="post-create-label"  column sm={ 2 }>
                    Features
                </Form.Label>
                <Col sm={ 10 }>
                    <TextFieldArray initialValues={{ features: [] } } name="features"/>
                </Col>
            </Form.Group>
            <Form.Group as={ Row }>
                <Col sm= { { span: 2, offset:2 } }>
                    <Button type="submit"  variant="primary">Submit</Button>
                </Col>
                <Col sm={ 2 }>
                    <Button variant="secondary">Save as draft</Button>
                </Col>
            </Form.Group>
        </Form>
    )}
</Formik>

Here, <TextFieldArray> is field array, I need to get values from field array when form is submitted.这里, <TextFieldArray>是字段数组,我需要在提交表单时从字段数组中获取值。

TextFieldArray:文本字段数组:

export const TextFieldArray = (props) => (
    <React.Fragment>
        <Formik initialValues= { props.initialValues } render={({ values }) => (
            <Form>
                <FieldArray name= { props.name } render={arrayHelper => (
                    <div>
                        { values[props.name] && values[props.name].length > 0 ?
                            (
                                values[props.name].map((item, index) => (
                                    <div key={index}>
                                        <Form.Group as= { Row }>
                                            <div className="col-md-8">
                                                <Field name={`${props.name}.${index}`}
                                                       className="form-control"/>
                                            </div>
                                            <div className="col-md-2">
                                                <Button type="button" variant="outline-secondary"
                                                        onClick={() => arrayHelper.remove(index)}>
                                                    Remove
                                                </Button>
                                            </div>
                                            <div className="col-md-2">
                                                <Button type="button" variant="outline-secondary"
                                                    onClick={() => arrayHelper.insert(index, '')}>
                                                    Add
                                                </Button>
                                            </div>
                                        </Form.Group>
                                    </div>
                                ))
                            ) : (
                                <Button type="button" variant="outline-secondary"
                                        onClick={() => arrayHelper.push('')} >
                                   {`Add ${ props.name }`}
                                </Button>
                            )
                        }
                    </div>
                )} />
            </Form>
        )} />
    </React.Fragment>
);

I'm a beginner to ReactJS, so someone help me please, that will be huge help from you all.我是 ReactJS 的初学者,所以请有人帮助我,这将是你们所有人的巨大帮助。 Thanks.谢谢。

To have field array be part of same form as other fields, only have one <Formik> and one <Form> .要让字段数组成为与其他字段相同的表单的一部分,只有一个<Formik>和一个<Form> Then make initialValues on Formik that describes all the fields:然后在描述所有字段的 Formik 上创建 initialValues:

<Formik
  initialValues={{ friends: someFriends, random: randomText }}

As seen in the following code from Formik FieldArray docs, with another form field added that is not part of the array:从 Formik FieldArray 文档的以下代码中可以看出,添加了另一个不属于数组的表单字段:

import React, { useState } from "react";
import ReactDOM from "react-dom";
import { Formik, Form, Field, useField, FieldArray } from "formik";

const someFriends = ["jared", "ian", "brent"];
const randomText = "Four score and seven years ago...";

function MyTextInput({ label, ...props }) {
  // useField() returns [formik.getFieldProps(), formik.getFieldMeta()]
  // which we can spread on <input> and alse replace ErrorMessage entirely.
  const [field, meta] = useField(props);
  return (
    <>
      <label
        htmlFor={props.id || props.name}
        css={{ backgroundColor: props.backgroundColor }}
      >
        {label}
      </label>
      <input className="text-input" {...field} type="text" {...props} />
      {meta.touched && meta.error ? (
        <div className="error">{meta.error}</div>
      ) : null}
    </>
  );
}

// Here is an example of a form with an editable list.
// Next to each input are buttons for insert and remove.
// If the list is empty, there is a button to add an item.
export const FriendList = () => (
  <div>
    <h1>Friend List</h1>
    <Formik
      initialValues={{ friends: someFriends, random: randomText }}
      onSubmit={values =>
        setTimeout(() => {
          alert(JSON.stringify(values, null, 2));
        }, 500)
      }
      render={({ values }) => (
        <Form>
          <MyTextInput label="Random comment" name="random" />
          <FieldArray
            name="friends"
            render={arrayHelpers => (
              <div>
                {values.friends &&
                  values.friends.length > 0 &&
                  values.friends.map((friend, index) => (
                    <div key={index}>
                      <Field name={`friends.${index}`} />
                      <button
                        type="button"
                        onClick={() => arrayHelpers.remove(index)} // remove a friend from the list
                      >
                        -
                      </button>
                      <button
                        type="button"
                        onClick={() => arrayHelpers.insert(index, "")} // insert an empty string at a position
                      >
                        +
                      </button>
                    </div>
                  ))}

                {/* Add a new empty item at the end of the list */}
                <button type="button" onClick={() => arrayHelpers.push("")}>
                  Add Friend
                </button>

                <div>
                  <button type="submit">Submit</button>
                </div>
              </div>
            )}
          />
        </Form>
      )}
    />
  </div>
);

ReactDOM.render(<FriendList />, document.getElementById("root"));

Code in codesandbox .代码箱中的代码

I don't think you need to create second form for child component.我认为您不需要为子组件创建第二种形式。
You need to just pass the values from the parent to the TextFieldArray您只需将值从父级传递给 TextFieldArray

    <TextFieldArray values={values.myArr} name="features"/>     

And the child component just receive the values and render them (as if it was in the parent component)子组件只是接收值并渲染它们(就像它在父组件中一样)

export const TextFieldArray = (props) => {
return (
    <React.Fragment>
                    <FieldArray
                        name= { props.name }
                        render={arrayHelper => (
                            <div>
                                {
                                    props.values[props.name] && props.values[props.name].length > 0 ?
                                        (
                                            props.values[props.name].map((item, index) => (
                                                <div key={index}>
                                                    <Form.Group as= { Row }>
                                                        <div className="col-md-8">
                                                            <Field name={`${props.name}.${index}`} className="form-control"/>
                                                        </div>
                                                        <div className="col-md-2">
                                                            <Button type="button" variant="outline-secondary"
                                                                onClick={() => arrayHelper.remove(index)}>
                                                                Remove
                                                            </Button>                                                              
                                                        </div>
                                                        <div className="col-md-2">
                                                            <Button type="button" variant="outline-secondary"
                                                                onClick={() => arrayHelper.insert(index, '')}
                                                            >
                                                                Add
                                                            </Button> 
                                                        </div>
                                                    </Form.Group>
                                                </div>
                                            ))
                                        ) : (
                                            <Button type="button" variant="outline-secondary" onClick={() => arrayHelper.push('')} >
                                               {`Add ${ props.name }`}
                                            </Button>
                                        )
                                }
                            </div>
                        )}
                    />
    </React.Fragment>
)

Of course don't forget to add the initial values of the array to the parent component.当然不要忘记将数组的初始值添加到父组件中。

And finally when you click on the submit button it would give you the values.最后,当您单击提交按钮时,它会为您提供值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM