在Formik FieldArray中访问嵌套数组

时间:2020-09-22 13:02:41

标签: javascript reactjs formik

**编辑:请检查更新的sandbox,其中包含以下答案中建议的一些更改。 **

我正在使用Formik及其<FieldArray ../>组件来处理一些嵌套数据以呈现输入。我不太清楚在ft.中将什么确切的字符串传递给名称prop。

在我的组件中,我有一个用户选择,可以过滤掉一些数据并返回此数组。

<FieldArray name={ // here}

我想访问"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": "" } ] 数组。我将错误的字符串传递给ipv4Addresses或未正确使用name中的索引。目前,我有以下内容:

.map

我有一个codesanbox that may provide some more context.

进一步研究之后,基本上我需要提供字符串值 <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`} component="div" className="field-error" /> ,因此我可能需要重新考虑.map及其实际返回的内容。

3 个答案:

答案 0 :(得分:4)

在另一个.map内有一个.map时,您可能会混淆index的值。尝试为index命名一些特定于每个.map的名称(例如deviceIndexaddressIndex)。我在下面的答案中使用了addressIndex进行内部地图操作。


似乎您的<FieldArray>应该只关心当前ipv4Addresses对象上的chosenDevice数组。

尝试一下:

<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}`}
                  component="div"
                  className="field-error"
                />

但是,如果我对此有误,并且<FieldArray>标记 需要引用它是哪个chosenDevice的子代,则应该这样做:

<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}`}
                  component="div"
                  className="field-error"
                />

答案 1 :(得分:1)

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\UsoSvc

如果您要在下面的地图中使用<FieldArray name={`chosenDevice.ipv4Addresses[${index}]`}> ,那么这是错误的,因为您不会在地图之外获得索引。

index上方使用此地图,如下所示:

FieldArray

答案 2 :(得分:0)

  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

看看我如何更新状态,这可能有助于实现您的结果。