React Hooks : How to manage your form state dynamically using a custom hook
Tags: react
Published: 2020-09-05 16:23:26

Hello community, 
 
In this post, I'm going to show you how to manage your form state dynamically using a custom hook in a few steps.

## So first, what are hooks?
Hooks are a new addition in React 16.8 to let you use state and other React features without writing a class, and the funniest thing is that you can build your own custom Hook.
Custom Hooks allow us to abstract the business logic from the component and make it reusable cross other components.


##1. Create a react-app :
```
npx create-react-app manage-form-state
```
##2. Build our form:
  
```javascript
// app.js
import React from 'react';

function App() {

  const formHandler = e => {
    e.preventDefault();
    console.log('form handler');
  }
  
  return (
    <div className="App">
      <form onSubmit={formHandler}>
        Name : <input type='text' /> <br />

        Email : <input type='email' /><br />

        Address : <input type='text' /><br />

        Phone : <input type='text' /><br />

        Password : <input type='password' /><br />
                          
        <input type='submit' value='Submit' />
      </form>
    </div>
  );
}

export default App;
```

##3. Create a formReducer function : 
```javascript
//form-reducer.js
const formReducer = (state, action) => {
    switch (action.type) {
        case 'INPUT_CHANGE':
            return {
                ...state,
                inputs: {
                    ...state.inputs,
                    [action.inputId]: action.value
                }
            }
        default:
            return state;
    }
}

export default formReducer;
```

##4. Create our 'useForm' custom hook :
 
```javascript
//form-hook.js
import { useReducer } from 'react';
import formReducer from  './form-reducer';

export const useForm = (initialInputs) => {
    const [formState, diaspatch] = useReducer(formReducer, {
        inputs: initialInputs
    });

    const inputHandler = (id, value) => {
        diaspatch({
            type: 'INPUT_CHANGE',
            value: value,
            inputId: id
        })
    }

    return [formState, inputHandler];
};
```

##5. Implement the 'useForm' logic in our form :
 first, we have to import our useForm hook and initialize the state
```javascript
import React from 'react';
import './App.css';
import { useForm } from './form-hook';

function App() {
  const [formState, inputHandler] = useForm({
    name: '',
    email: '',
    address: '',
    phone: '',
    password: ''
  });
```
Now we need another function that will call the inputHandler when the input value change
```javascript
const changeHandler = e  => {
     const {id,value} = e.currentTarget;
     inputHandler(id,value);
  }
```
finally, we are ready to update our form 
```javascript
 const { name,email,address,phone,password } = formState.inputs;
  return (
    <div className="App">
      <form onSubmit={formHandler}>
        Name : <input type='text' id='name' 
                     value={name} 
                     onChange={changeHandler} /> <br />

        Email : <input type='email' id='email' 
                       value={email} 
                       onChange={changeHandler} /><br />

        Address : <input type='text' id='address' 
                         value={address}
                          onChange={changeHandler} /><br />

        Phone : <input type='text' id='phone' 
                       value={phone} 
                       onChange={changeHandler} /><br />

        Password : <input type='password' id='password' 
                          value={password} 
                          onChange={changeHandler} /><br />
                          
        <input type='submit' value='Submit' />
      </form>
    </div>
```