Formik: `FieldArray` in `FieldArray`

Created on 10 Mar 2019  路  2Comments  路  Source: formium/formik

鉂換uestion

Hi guys,
I'm actually trying to build complex form using Formik but i'm actually blocked. Is that possible to use a FieldArray inside another FieldArray ?

I'm actually trying but when i try to add an item in the child FieldArray, it's actually add an element in the parent FieldArray

Something like that :

<FieldArray
  name="parents"
  render={parentsArray => (
    <View>
      {props.values.parents.map((part, parentIndex) => (
        <View key={parentIndex}>
          <Text>A parent</Text>

          ## Child FieldArray
          <FieldArray
            name="children"
            render={childrenArray => (
              <View>
                {props.values.parents[parentIndex].map((part, childrenIndex) => (
                  <View key={parentIndex}>
                    <Text>A child</Text>
                  </View>
                ))}
                <TouchableOpacity onPress={() => childrenArray.push({ name: 'children name' })}>
                  <Text>Add a child</Text>
                </TouchableOpacity>
              </View>
            )}
          />

        </View>
      ))}
      <TouchableOpacity onPress={() => parentsArray.push({ name: 'parent name', childs: [] })}>
        <Text>Add a parent</Text>
      </TouchableOpacity>
    </View>
  )}
/>

Most helpful comment

What you miss is setting correct name prop on inner FieldArray that would point to correct value in Formik's values prop.

Please, see this codesandbox https://codesandbox.io/s/ojmk5rzlwq
Code for future reference

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

import "./styles.css";

const INITIAL_VALUES = {
  dates: [
    { date: "2019-03-10", events: ["Late night run"] },
    { date: "2019-03-11", events: ["Netflix and chill"] },
  ],
};

function App() {
  return (
    <Formik initialValues={INITIAL_VALUES}>
      <Form>
        <FieldArray name="dates">
          {arrayHelpers => {
            const dates = getIn(arrayHelpers.form.values, arrayHelpers.name);
            return dates.map((day, index) => (
              <EventEditor
                key={day.date}
                name={`${arrayHelpers.name}.${index}`}
              />
            ));
          }}
        </FieldArray>
      </Form>
    </Formik>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

function EventEditor(props) {
  return (
    <Field name={props.name}>
      {fieldProps => (
        <div style={{ marginBottom: 20 }}>
          <div>{fieldProps.field.value.date}</div>
          <FieldArray name={`${fieldProps.field.name}.events`}>
            {arrayHelpers => (
              <React.Fragment>
                <div>
                  {fieldProps.field.value.events.map((event, index) => (
                    <div key={index}>
                      {event}
                      <button
                        type="button"
                        onClick={() => arrayHelpers.remove(index)}
                      >
                        remove
                      </button>
                    </div>
                  ))}
                </div>
                <button
                  type="button"
                  onClick={() => {
                    arrayHelpers.push(prompt("What are you up to?"));
                  }}
                >
                  add
                </button>
              </React.Fragment>
            )}
          </FieldArray>
        </div>
      )}
    </Field>
  );
}

All 2 comments

What you miss is setting correct name prop on inner FieldArray that would point to correct value in Formik's values prop.

Please, see this codesandbox https://codesandbox.io/s/ojmk5rzlwq
Code for future reference

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

import "./styles.css";

const INITIAL_VALUES = {
  dates: [
    { date: "2019-03-10", events: ["Late night run"] },
    { date: "2019-03-11", events: ["Netflix and chill"] },
  ],
};

function App() {
  return (
    <Formik initialValues={INITIAL_VALUES}>
      <Form>
        <FieldArray name="dates">
          {arrayHelpers => {
            const dates = getIn(arrayHelpers.form.values, arrayHelpers.name);
            return dates.map((day, index) => (
              <EventEditor
                key={day.date}
                name={`${arrayHelpers.name}.${index}`}
              />
            ));
          }}
        </FieldArray>
      </Form>
    </Formik>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

function EventEditor(props) {
  return (
    <Field name={props.name}>
      {fieldProps => (
        <div style={{ marginBottom: 20 }}>
          <div>{fieldProps.field.value.date}</div>
          <FieldArray name={`${fieldProps.field.name}.events`}>
            {arrayHelpers => (
              <React.Fragment>
                <div>
                  {fieldProps.field.value.events.map((event, index) => (
                    <div key={index}>
                      {event}
                      <button
                        type="button"
                        onClick={() => arrayHelpers.remove(index)}
                      >
                        remove
                      </button>
                    </div>
                  ))}
                </div>
                <button
                  type="button"
                  onClick={() => {
                    arrayHelpers.push(prompt("What are you up to?"));
                  }}
                >
                  add
                </button>
              </React.Fragment>
            )}
          </FieldArray>
        </div>
      )}
    </Field>
  );
}

Thanks for your response !
I got it, didn't understand i have to use the Formik.values in the FieldArray name props but seems logic now.

Thanks !

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jaredpalmer picture jaredpalmer  路  3Comments

dearcodes picture dearcodes  路  3Comments

jaredpalmer picture jaredpalmer  路  3Comments

jaredpalmer picture jaredpalmer  路  3Comments

green-pickle picture green-pickle  路  3Comments