Skip to content
Advertisement

React Hooks: handle multiple inputs

on react docs forms section there is the following example using class components:

class Reservation extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isGoing: true,
      numberOfGuests: 2
    };

    this.handleInputChange = this.handleInputChange.bind(this);
  }

  handleInputChange(event) {
    const target = event.target;
    const value = target.type === 'checkbox' ? target.checked : target.value;
    const name = target.name;

    this.setState({
      [name]: value
    });
  }

  render() {
    return (
      <form>
        <label>
          Is going:
          <input
            name="isGoing"
            type="checkbox"
            checked={this.state.isGoing}
            onChange={this.handleInputChange} />
        </label>
        <br />
        <label>
          Number of guests:
          <input
            name="numberOfGuests"
            type="number"
            value={this.state.numberOfGuests}
            onChange={this.handleInputChange} />
        </label>
      </form>
    );
  }
}

Considering Hooks can only be called either in a React function component or a custom React Hook function is there a way of doing it using hooks instead?

Advertisement

Answer

example

const MyComponent = () => {
   const [inputs,setInputs] = useState({});

   return (
     <> 
      <input key="field1" name="field1" onChange={({target}) => setInputs(state => ({...state,field1:target.value}))} value={inputs.field1}/>
      <input key="field2" name="field2" onChange={({target}) => setInputs(state => ({...state,field2:target.value}))} value={inputs.field2}/>
     </>
   )

}

you can pass in initial values like this:

const MyComponent = (initialValues = {}) => {
   const [inputs,setInputs] = useState(initialValues);
   ...
}

EDIT: A nice short onChange according to @hamidreza‘s comment

const MyComponent = (initialValues = {}) => {
   const [inputs,setInputs] = useState(initialValues);
   const onChangeHandler = useCallback(
     ({target:{name,value}}) => setInputs(state => ({ ...state, [name]:value }), [])
   );

   return (
     <> 
      <input key="field1" name="field1" onChange={onChangeHandler} value={inputs.field1}/>
      <input key="field2" name="field2" onChange={onChangeHandler} value={inputs.field2}/>
     </>
   )


}

etc, etc, etc

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement