React hooks (intermedian): useStateForm
Tags: react, hooks, javascript
Published: 2019-09-22 15:55:13

> *Note: make sure you understand the basics about react hooks, in the near future i will made posts about this.*

## Problem :weary:
As you may know managing the state of a form is a pain-hell, you need to create an object state, the methods to manage the changes in the inputs and be careful with the data you are changing. Some libraries like Formik abstract the state and provide some useful components that work with it. But as my known Formik is complicated to use and complicated to read, sometimes you will need the high-order component and sometimes the render-prop component but both options create code difficult to understand.

## Solution

__Use React Hooks__ :grin:

### Context :open_mouth:

If you like be updated with the new versions of React, for sure you heard about the React hooks and as the documentation says:

> __Hooks allow you to reuse stateful logic without changing your component hierarchy__

React hooks are functions that allow us *hook in* the state and render phases of our component, and the best part is that we can create __custom hooks__ to solve specific problems.

But how to use hooks to manage our form? well that's why i write this post :nerd_face:

### Ok here we go! :sweat_smile:

Think in the problem, first we need to abstract the state management into a custom hook and this custom hook needs to give us access to its state, in the below code we can see a simple implementation of the hooks to handle the state form.

```javascript
function MyForm(props) {
  const [formState, setFormState] = useState({...});
  const handleChanges = (event) => {...};
  
  return (
  	...
    <input
      onChange={handleChanges}
  	  value={formState.prop1}
  	  name="prop1"
    />
    ...
  )
}
```

To abstract the state create a custom hook called __useStateForm__ there use the hook *useState* to handle the state and return it to keep it visible to the components. Also we need to pass the initialState of our form to the custom hook.

```javascript
function useStateForm(initialState) {
  const [formState, setFormState] = useState(initialState);
  
  return formState
}
```

Cool! the state is handle in our custom hook, but now we need some handleChange implementation to change our state 🤔.
```javascript
function useStateForm(initialState) {
  const [formState, setFormState] = useState(initialState);
  const handleChanges = (event) => {
    setFormState({
      ...formState,
      [event.target.name]: event.target.value
    })
  };
  return { formState, handleChanges };
}
```
Awesome! our state is full abstracted, as you can see this is basically the same component without the render return statement and this is the power of hooks, now we can reuse common state functionality and share it between our components very easy, this will allow us save a lot of type coding. Now our component will looks like this:

```javascript
function MyForm(props) {
  const {formState, handleChanges} = useStateForm({ prop1: '' });
  
  return (
  	...
    <input
      onChange={handleChanges}
      value={formState.prop1}
      name="prop1"
    />
    ...
  )
}
```

Now we can go far away, what if instead of let the programmer the responsibility to set correctly the name of the inputs, our custom hook take care of that. What about validate the form state, or sometimes we need to format our raw data. Well all that you can find in my github project:

{% github miguelromerogutierrez/react-state-form no-readme %}