If I use formik, how can I write the correct value in the nested object?
P粉410239819
P粉410239819 2023-08-17 16:26:31
0
1
553
<p>Given an array of fields that match the field names in the form object, I'm trying to write a nested value, but for some reason formik doesn't know how to write a nested value, this only works for the top level value< ;/p> <p>I will leave a link to codesandbox in the comments</p> <pre class="brush:php;toolbar:false;">export default function App() { const form = useFormik({ initialValues: { name: "", login: "", about: { age: "", rank: "", car: { name: "", years: "" } } } }); const fields = [ { name: { title: "Your name", fields: {} }, login: { title: "Your login", fields: {} }, about: { title: "About", fields: { age: { title: "Your age", fields: {} }, rank: { title: "Your rank", fields: {} }, car: { title: "Your car", fields: { name: { title: "Car name", fields: {} }, years: { title: "Car years", fields: {} } } } } } } ]; const { values, handleChange } = form; console.log("VALUES", values); const itemsRender = (item, idx) => { const key = Object.keys(item).at(-1); return ( <div key={idx}> <p>{item[key]?.title}</p> <input name={key} value={values[key]} onChange={handleChange} placeholder={item[key].title} /> {!isEmpty(item[key]?.fields) && ( <div style={{ marginLeft: 20 }}> {Object.entries(item[key]?.fields).map(itemsRender)} </div> )} </div> ); }; return <>{fields.map(itemsRender)}</>; }</pre>
P粉410239819
P粉410239819

reply all(1)
P粉046878197

You need to update the name and value properties to include the full path to the nested field

<input
  name={`${key}.${nestedFieldName}`} // 包含嵌套字段的路径
  value={getIn(values, `${key}.${nestedFieldName}`)} // 使用formik的getIn获取嵌套值
  onChange={handleChange}
  placeholder={fieldObj.title}
/>

Your code only handles one level of nesting.
For deeper nesting, you need to render and process the nested fields recursively

{Object.entries(item[key]?.fields).map(([nestedFieldName, fieldObj]) => (
  <div style={{ marginLeft: 20 }} key={nestedFieldName}>
    <p>{fieldObj.title}</p>
    <input
      name={`${key}.${nestedFieldName}`}
      value={getIn(values, `${key}.${nestedFieldName}`)}
      onChange={handleChange}
      placeholder={fieldObj.title}
    />
    {fieldObj.fields && (
      <div style={{ marginLeft: 20 }}>
        {Object.entries(fieldObj.fields).map(itemsRender)}
      </div>
    )}
  </div>
))}

Finally, do not use handleChange to handle nested fields directly. Instead, use Formik's setFieldValue to update the value of the nested field.
You can access setFieldValue from the form object:

onChange={(e) => {
  form.setFieldValue(`${key}.${nestedFieldName}`, e.target.value);
}}

codesandbox

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template