0

I have a form which consists from several input blocks. The blocks are the same (I mean they all have the same fields set). Each block has an input field name.

On Submit I want to get an object like this:

const resultInput = {
    block1: {
        name: ''
    },
    block2: {
        name: ''
    }
}

I can achieve that with multiple states and on submit combine them into the result object like this:

  const [firstBlockInput, setFirstBlockInput] = useState({});
  const [secondBlockInput, setSecondBlockInput] = useState({});

  const handleChangeFirstBlock = (e) => {
    const { name, value } = e.target;

    setFirstBlockInput((prev) => ({
      ...prev,
      [name]: value,
    }));
  };


  const handleChangeSecondBlock = (e) => {
    const { name, value } = e.target;

    setSecondBlockInput((prev) => ({
      ...prev,
      [name]: value,
    }));
  };

  const handleSubmit = () => {
    const result = {
      block1: firstBlockInput,
      block2: secondBlockInput,
    };

    console.log(result);
  };

Also I have to pass these states and onChanges functions down to child form like this:

  <SomeForm
    onClose={closeForm}
    onChangeBlock1={handleChangeFirstBlock}
    onChangeBlock2={handleChangeFirstBlock}
    firstBlockInputValue={firstBlockInput}
    secondBlockInputValue={secondBlockInput}
    onSubmit={handleSubmit}
  />

And here's my question. Is there a simple and clean approach to do the same but without extra states and functions (like handleChange for each input)? Example above is simplified...actually I have three blocks and each has three input fields.

1 Answer 1

1

Yes there is a much simpler way if you are fine with a 2D dictionary.

You can provide handleChange in your <SomeForm> with a key, and the event. Theoretical example:

  const [blockInput, setBlockInput] = useState({});

  const handleChange = (key, e) => {
    const { name, value } = e.target;

    setBlockInput((prev) => ({
      ...prev,
      [key]: {
         [name]: value,
      }
    }));
  };

  <SomeForm
    onChange={handleChange}
  />

Usage example:

<element onChange={(e) => onChange("block1", e)}/>
Sign up to request clarification or add additional context in comments.

1 Comment

There is a bug in setBlockInput. Probably [key]: { ...prev[key], [name]: value }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.