alimukhtor
alimukhtor

Reputation: 13

how to update nested object of array in useState hook in react?

I have a component that has nested objects in array:

  const [documentObj, setDocument] = useState({
    document_name: "",
    form_values: [
      {
        field_seq: null,
        is_mandatory: false,
        field_type: null,
        field_name: "",
        select_values: [
          {
            value: false,
            label: "",
          },
        ],
      },
    ],
  });

I'm trying to update the object properties, but when I try to update the object, it is saying can not reay properties [0]

this is how I'm updating it:


<Form.Control
 type="number"
 value={documentObj.form_values[0].field_seq}
 onChange={(event) => {
  setDocument((prevStyle) => ({
  ...prevStyle,
form_values: [
{
...prevStyle.form_values,
field_seq: event.target.value,
},
],
}));
}}
/>
</Form.Group>

Probably i need to write a function to handle all input value and need some help

Upvotes: 0

Views: 1136

Answers (3)

John Li
John Li

Reputation: 7447

Update 2

It seems that documentObj.form_values[0] is unlikely to be undefined in the posted code, but maybe it could be in the actual project.

As an attempt to address the error perhaps also consider to check for undefined where this is used, such as in value:

value={documentObj.form_values[0]?.field_seq || ""}

Update

While not specified in the post, if Form.Control is from react-bootstrap, according to their doc the value property need to be string | arrayOf | number.

Perhaps also try set an empty string "" as the initial value of field_seq, so this component is fully controlled:

const [documentObj, setDocument] = useState({
  document_name: "",
  form_values: [
    {
      // 👇 Initial value as empty string
      field_seq: "",
      is_mandatory: false,
      field_type: null,
      field_name: "",
      select_values: [
        {
          value: false,
          label: "",
        },
      ],
    },
  ],
});

There might be other issues, but hope that this could still help locating some errors.

Original

Perhaps the intended property to read was ...prevStyle.form_values[0]?

Not sure if there are other issues without checking the error message, but could probably try the following in setDocument to see if it improves:

<Form.Control
  type="number"
  value={documentObj.form_values[0].field_seq}
  onChange={(event) => {
    setDocument((prevStyle) => ({
      ...prevStyle,
      form_values: [
        {
          // 👇 Added [0] here
          ...prevStyle.form_values[0],
          field_seq: event.target.value,
        },
      ],
    }));
  }}
/>

Upvotes: 2

Azzy
Azzy

Reputation: 1731

replacing the items in form_values based on index

<Form.Control
      type="number"
      value={documentObj.form_values[0]?.field_seq ?? ''}
      onChange={(event) => {
        setDocument((prevStyle) => {
   
    
           const newFormValues = [];
    
           if (!!prevStyle.form_values?.length) {
                              // if the form_values was empty 
           const newFormValue = { 
                 // might want to include some default data
                 field_seq: event.target.value 
           }
               newFormValues.push(newFormValue)
           } else {
                //replace first item form_values 
                newFormValues = prevStyle.form_values.map((e, idx) => {
                       if (idx === 0) {
                           return {
                              ...e,
                              field_seq: event.target.value 
                           }
                       } else {
                            return e;
                       }
                })
           }
    
     
           return {
              ...prevStyle,
              form_values: newFormValues
           }
    
    }}
    />
    </Form.Group>

Hope it helps

Upvotes: 0

Ayush pathak
Ayush pathak

Reputation: 1

const [documentObj, setDocument] = useState({ document_name: "", form_values: [ { field_seq: null, is_mandatory: false, field_type: null, field_name: "", select_values: [ { value: false, label: "", }, ], }, ], });

Upvotes: 0

Related Questions