Home > Enterprise >  How to add a new item to an array of objects in React useState
How to add a new item to an array of objects in React useState

Time:10-11

I am building an app using react and Typescript that reserves seats for people. I am using useState hook to manage the form inputs. However I am unable to update my state (shown below)

Here is the state and its type

import { useState } from "react"

type infoInputsType = {
  eventName?: string
  participants?: [{
    id?: number
    name?: string
  }]
}


const create = () => {

 const [infoInputs, setInfoInputs] = useState<infoInputsType>({})
 
 return(
  <div>
    <form>
       <input
              value={infoInputs.eventName}
              onChange={(e) =>
                setInfoInputs({ ...infoInputs, eventName: e.target.value })
              }
              type="text"
        />
        
        // error occurs below
        <input
              value={infoInputs.participants?[0].id}
              onChange={(e) =>
                setInfoInputs({
                  ...infoInputs,
                  participants:[...participants,{id: parseInt(e.target.value!}]
                })
              }
              type="number"
            />
        
        
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

The goal is to be able to add several participant objects to the participants array and to get something similar to this

infoInputsType = {
      eventName?: 'Chess tournament'
      participants?: [
       {
        id?: 01
        name?: 'Magnus'
      },
      {
        id?: 04
        name?: 'Hikaru'
     ]
    }

However adding new objects to the state like this does not work. What to do?

<input
              value={infoInputs.participants?[0].id}
              onChange={(e) =>
                setInfoInputs({
                  ...infoInputs,
                  participants:[...participants,{id: parseInt(e.target.value!}]
                })
              }
              type="number"
            />

CodePudding user response:

Note that you're using ...participants when you update the state - where did that come from? JS doesn't magically know that you have a participants property in infoInputs.

BTW, I would recommend you to use the functional form of setState since you are relying on the existing information in infoInputs:

<input
              value={infoInputs.participants?[0].id}
              onChange={(e) =>
                setInfoInputs((i) => {
                  ...i,
                  participants:[...i.participants,{id: parseInt(e.target.value!}]
                })
              }
              type="number"
            />

CodePudding user response:

Make different state for different field entry and then onSubmit, structure all that data in your desired format.


Use redux or useReducer hook to manage complex states.

  • Related