最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Accessing nested array in Formik FieldArray - Stack Overflow

programmeradmin3浏览0评论

**EDIT: Please check the updated sandbox, it incorporates some of the changes suggested in the below answer. **

I'm using Formik and its <FieldArray ../> ponent to handle some nested data to render inputs. I can't quite figure out what exact string to pass to the name prop in <FieldArray name={ // here}.

In my ponent I have a user selection that filters out some data and returns this array.

"chosenDevice": [
  {
    "deviceName": "eth0",
    "macAddress": "01:40:27:0F:2E:CB",
    "ipv4DHCP": false,
    "ipv4Addresses": [
      "182.148.1.100/24"
    ],
    "ipv4Gateway": "",
    "ipv6DHCP": false,
    "ipv6Addresses": [
      "232.232.2/100/10"
    ],
    "ipv6Gateway": ""
  }
]

I want to access the ipv4Addresses array. I'm either passing the wrong string to name or not using index in .map properly. Currently I have the following:

    <FieldArray
  name={`chosenDevice.ipv4Addresses[${index}]`}
>
  {({ remove, push }) => (
    <>
      <div>
        {values.chosenDevice.length > 0 &&
          values.chosenDevice.map(
            (ipv4Addresses, index) => (
              <div
                style={{
                  display: "flex"
                }}
                key={index}
              >
                <label
                  htmlFor={`chosenDevice[${index}].ipv4Addresses`}
                  className="custom-label"
                  style={{ flex: 1 }}
                >
                  ipv4Address(es)
                  <Field
                    className="custom-input"
                    name={`chosenDevice[${index}].ipv4Addresses`}
                    placeholder="< ipv4Address >"
                    type="text"
                  />
                </label>
                <ErrorMessage
                  name={`chosenDevice.${index}.ipv4Addresses`}
                  ponent="div"
                  className="field-error"
                />

I have a codesanbox that may provide some more context.

After looking into this further, basically I need to provide the string value of deviceName[0].ipv4Addresses[0], so I may need to rethink the .map and what it's actually returning.

**EDIT: Please check the updated sandbox, it incorporates some of the changes suggested in the below answer. **

I'm using Formik and its <FieldArray ../> ponent to handle some nested data to render inputs. I can't quite figure out what exact string to pass to the name prop in <FieldArray name={ // here}.

In my ponent I have a user selection that filters out some data and returns this array.

"chosenDevice": [
  {
    "deviceName": "eth0",
    "macAddress": "01:40:27:0F:2E:CB",
    "ipv4DHCP": false,
    "ipv4Addresses": [
      "182.148.1.100/24"
    ],
    "ipv4Gateway": "",
    "ipv6DHCP": false,
    "ipv6Addresses": [
      "232.232.2/100/10"
    ],
    "ipv6Gateway": ""
  }
]

I want to access the ipv4Addresses array. I'm either passing the wrong string to name or not using index in .map properly. Currently I have the following:

    <FieldArray
  name={`chosenDevice.ipv4Addresses[${index}]`}
>
  {({ remove, push }) => (
    <>
      <div>
        {values.chosenDevice.length > 0 &&
          values.chosenDevice.map(
            (ipv4Addresses, index) => (
              <div
                style={{
                  display: "flex"
                }}
                key={index}
              >
                <label
                  htmlFor={`chosenDevice[${index}].ipv4Addresses`}
                  className="custom-label"
                  style={{ flex: 1 }}
                >
                  ipv4Address(es)
                  <Field
                    className="custom-input"
                    name={`chosenDevice[${index}].ipv4Addresses`}
                    placeholder="< ipv4Address >"
                    type="text"
                  />
                </label>
                <ErrorMessage
                  name={`chosenDevice.${index}.ipv4Addresses`}
                  ponent="div"
                  className="field-error"
                />

I have a codesanbox that may provide some more context.

After looking into this further, basically I need to provide the string value of deviceName[0].ipv4Addresses[0], so I may need to rethink the .map and what it's actually returning.

Share Improve this question edited Sep 28, 2020 at 13:18 DJ2 asked Sep 22, 2020 at 13:02 DJ2DJ2 1,7513 gold badges37 silver badges76 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 4

With a .map inside of another .map, you might be getting index values confused. Try naming index something more specific to each .map (such as deviceIndex and addressIndex). I've used addressIndex for the inner map operation in my answer below.


It seems like your <FieldArray> here should only concern itself with the ipv4Addresses array on the current chosenDevice object.

Try this:

<FieldArray
  name="chosenDevice.ipv4Addresses"
>
  {({ remove, push }) => (
    <>
      <div>
        {chosenDevice.ipv4Addresses > 0 &&
          chosenDevice.ipv4Addresses.map(
            (ipv4Address, addressIndex) => (
              <div
                style={{
                  display: "flex"
                }}
                key={addressIndex}
              >
                <label
                  htmlFor={`chosenDevice.ipv4Addresses.${addressIndex}`}
                  className="custom-label"
                  style={{ flex: 1 }}
                >
                  ipv4Address(es)
                  <Field
                    className="custom-input"
                    name={`chosenDevice.ipv4Addresses.${addressIndex}`}
                    placeholder="< ipv4Address >"
                    type="text"
                  />
                </label>
                <ErrorMessage
                  name={`chosenDevice.ipv4Addresses.${addressIndex}`}
                  ponent="div"
                  className="field-error"
                />

But if I'm wrong about that, and the <FieldArray> tag does need to reference which chosenDevice it's a child of, this should do it:

<FieldArray
  name={`chosenDevice.${index}.ipv4Addresses`}
>
  {({ remove, push }) => (
    <>
      <div>
        {chosenDevice[index].ipv4Addresses > 0 &&
          chosenDevice[index].ipv4Addresses.map(
            (ipv4Address, addressIndex) => (
              <div
                style={{
                  display: "flex"
                }}
                key={addressIndex}
              >
                <label
                  htmlFor={`chosenDevice.${index}.ipv4Addresses.${addressIndex}`}
                  className="custom-label"
                  style={{ flex: 1 }}
                >
                  ipv4Address(es)
                  <Field
                    className="custom-input"
                    name={`chosenDevice.${index}.ipv4Addresses.${addressIndex}`}
                    placeholder="< ipv4Address >"
                    type="text"
                  />
                </label>
                <ErrorMessage
                  name={`chosenDevice.${index}.ipv4Addresses.${addressIndex}`}
                  ponent="div"
                  className="field-error"
                />
<FieldArray name={`chosenDevice.ipv4Addresses[${index}]`}>

The index here if you are trying to use from the map below, then this is wrong you'll not get index outside the map.

Use this map above the FieldArray, like this:

values.chosenDevice.map((ipv4Addresses, index) => (
 <FieldArray
  name={`ipv4Addresses[${index}]`}
>
  {({ remove, push }) => (
    <>
      <div>
              <div
                style={{
                  display: "flex"
                }}
                key={index}
              >
                <label
                  htmlFor={`chosenDevice[${index}].ipv4Addresses`}
                  className="custom-label"
                  style={{ flex: 1 }}
                >
                  ipv4Address(es)
                  <Field
                    className="custom-input"
                    name={`chosenDevice[${index}].ipv4Addresses`}
                    placeholder="< ipv4Address >"
                    type="text"
                  />
                </label>
                <ErrorMessage
                  name={`chosenDevice.${index}.ipv4Addresses`}
                  ponent="div"
                  className="field-error"
                />)
  const [configIdx, setConfigIdx] = useState(0);

 <FieldArray
           name={`chosenDevice.ipv4Addresses[${configIdx}]`}
                                    >
                                      {({ remove, push }) => (
                                        <>
                                          <div>
                                            {values.chosenDevice.length > 0 &&
                                              values.chosenDevice.map(
                                                (ipv4Addresses, index) => {
                                                  setConfigIdx(index);
                                                  return (
                                                    <div
                                                      style={{
                                                        display: "flex"
                                                      }}
                                                      key={index}
                                                    >
                                                      <label

See how I updating state, this might help to achieve your result.

发布评论

评论列表(0)

  1. 暂无评论