Home  >  Q&A  >  body text

How to update state in onChange event in case of array object

I have some status:

const [budget, setBudget] =
    React.useState<{ name: string; budget: number | null }[]>();

I'm trying to use a TextField to update that state based on the input field's name and value:

budget.map((item) => {
      content.push(
        <TextField
          name={item.name}
          id={item.name}
          label={item.name}
          type="tel"
          onChange={handleChange}
        />
      );
    });

I know this is a weird situation, but the input fields are not predetermined values ​​so I have to render them dynamically which makes life difficult.

I tried the following onChange function but it doesn't work:

const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => () => {
    const newOne = budget?.map((item) =>
      Object.entries(item).map(([key, value]) => {
        if (key === event.target.name) {
          return [key, event.target.value];
        }
        return [key, value];
      })
    );
    setBudget(newOne);
  };

I accidentally created a lot of arrays and got the following error (not sure how to return just the keys and values):

Argument of type '(string | number | null)[][][] | undefined' is not assignable to parameter of type 'SetStateAction<{ name: string; budget: number | null; }[] | undefined>'.

P粉726234648P粉726234648370 days ago464

reply all(1)I'll reply

  • P粉993712159

    P粉9937121592023-09-18 15:16:17

    I think the problem is that you are using a double arrow function in the handleChange function, which means that when the event occurs, the inner function is not actually executed. You should get rid of the extra arrows.

    Another problem is that you are returning an array of arrays from the map function, which is incompatible with your state type. You should use Object.fromEntries to convert an array of arrays back to an array of objects. For example:

    const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
      const newOne = budget?.map((item) =>
        Object.fromEntries(
          Object.entries(item).map(([key, value]) => {
            if (key === event.target.name) {
              return [key, event.target.value];
            }
            return [key, value];
          })
        )
      );
      setBudget(newOne);
    };

    reply
    0
  • Cancelreply