REACT: Dynamical load multiple new HTML-Elements

Viewed 29

so I recently starte developing with React. I want to load multiple new Input Fields and Labels in a Form using Hooks in React. Heres my problem: When i click the button, only one input field gets created but it is using the last value of my array. When I check the console, I can see that it went through my loop multiple types and I don't know what i do wrong.

    const serverDescriptionFields = ["OS-Family", "OS-Version"];

    const [formValues, setFormValues] = useState([{ name: "", id: "" }]);
    let addFormFields = (name, id) => {
        setFormValues([...formValues, { name: name, id: id }]);
  };
    let makeApiCall = (event) => {
    for (const [i, description] of serverDescriptionFields.entries()) {
      addFormFields(
        serverDescriptionFields[i],
        serverDescriptionFields[i] + "Input"
      );
      console.info("field added");
    }

    return (
    <div className="form">
      <form onSubmit={makeApiCall}>
        <div className="form-inline">
          <Label>{props.name}</Label>
          <Input id={props.id} />{" "}
        </div>
        {formValues.map((element, index) => (
          <div className="form-inline" key={index}>
            {index ? (
              <>
                <Label>{element.name}</Label>
                <Input id={element.id} />{" "}
              </>
            ) : null}
          </div>
        ))}
        <div className="button-section">
          <Button className="button submit" type="submit">
            Check
          </Button>
        </div>
      </form>
    </div>
  );
1 Answers

I'm not sure why, but this is how it goes:

// formValues === 1
setFormValues(2);
// formValues === 1

I think it's related to the way React works under the hood, or whatever. Anyway, one would never update the state the way you did. This is how you can retrieve current value:

// formValues === 1
setFormValues(2);
// formValues === 1
setFormValues(actualValue => {
    // actualValue === 2
    return 3;
});

Alternatively, just set the whole array at once.

This should do it:

setFormValues(actualValues => [...actualValues, { name: name, id: id }]);
Related