score:1

Accepted answer

your question is a little confusing but it sounds like you want to have a form with dynamic number of rows. each row with a fixed number of inputs.

you can keep your state in a single array of objects, mapping over the array to render each row of inputs.

the input onchange handler will pass the array index and the event to a function.

you can get the value and input name from the event, which (along with the array index) is enough information to set the new state.

import { usestate } from "react";

export default function app() {

  const emptyreview = {
    reviewer: "",
    review: ""
  };

  const [results, setresults] = usestate([{ ... emptyreview }]);

  const onchange = (i, e) => {
    const { value, name } = e.currenttarget;
    const newresults = [...results];
    newresults[i] = {
      ...newresults[i],
      [name]: value
    };
    setresults(newresults);
  };

  const addreview = () => {
    const newresults = [...results, { ... emptyreview }];
    setresults(newresults);
  };

  return (
    <div classname="app">
      {results.map((result, i) => (
        <div key={i}>
          <div>
            <label>
              reviewer:
              <input
                value={result.reviewer}
                name="reviewer"
                onchange={(e) => onchange(i, e)}
              />
            </label>
          </div>
          <div>
            <label>
              review:
              <input
                value={result.review}
                name="review"
                onchange={(e) => onchange(i, e)}
              />
            </label>
          </div>
          <hr />
        </div>
      ))}
      <button onclick={addreview}>new review</button>
      <pre>{json.stringify(results)}</pre>
    </div>
  );
}

edit adoring-cloud-q04qj


bonus. if the inputs are just the same text input and label repeated, you could even map over the keys of the object from within the outer map. that way if you ever need to add extra fields, you would just do it in one place - the emptyreview object.

    {results.map((row, i) => (
      <div key={i} classname="row">
        {object.keys(row).map((key) => (
          <label key={key}>
            {key}
            <input
              value={row[key]}
              name={key}
              onchange={(e) => onchange(i, e)}
            />
          </label>
        ))}
      </div>
    ))}

edit musing-night-yx5pd


Related Query

More Query from same tag