Skip to content Skip to sidebar Skip to footer

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.sta

Solution 1:

example

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

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

}

you can pass in initial values like this:

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

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

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

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


}

etc, etc, etc

Solution 2:

you can clean up @adam 's final solution a bit by not using the useCallback hook, and instead simply using the useState hook as a controlled component.

constMyComponent = () => {
   const [inputs, setInputs] = useState({});
   consthandleChange = e => setInputs(prevState => ({ ...prevState, [e.target.name]: e.target.value }));

   return (
     <><inputname="field1"value={inputs.field1 || ''} onChange={handleChange} /><inputname="field2"value={inputs.field2 || ''} onChange={handleChange} /></>
   )
}

Solution 3:

Maybe, on the last example onChangeForField('...') will be triggered on each render, so maybe you have to write onChange={()=>onChangeForField('...')} or if you want the event to get passed onChange={(e)=>onChangeForField('...', e)}

Solution 4:

adding to Adam's answer and for those who are looking towards typescript solution,

interfaceMyIType {
    field1: string;
    ...
}

//Partial from typescript to make properties optionalinterfaceMyFormTypeextendsPartial<MyIType> {}

const [inputs,setInputs] = useState<MyFormType>(initialValues);
    
const onChangeForField = useCallback(({target}) =>setInputs(_state => {
            return {
                ..._state,
                [target.name]: target.value,
            };
        }),
    []
);

Solution 5:

If you were like me, having multiple inputs on multiple pages using the same input id/name/key, try value={data.xxx || ''} . Full code:

const [data, setData] = useState<any>({});

const handleValueChanges = e => { 
    setData({
      ...data,
      [e.target.name]: e.target.value,
    });
};

<InputText  (using prime react)
    id="firstName"
    name="firstName"
    value={data.firstName || ''}
    onChange={handleUpdate}
/>

Post a Comment for "React Hooks: Handle Multiple Inputs"