React Ionic Framework and Hooks
Tags: javascript, react, reacthooks, ionic
Published: 2019-09-24 04:04:04

---
title: React Ionic Framework and Hooks
published: true
description: building a sample application using react hooks api, useState & useReducer
tags: #javascript #react #reacthooks #ionic
cover_image: https://thepracticaldev.s3.amazonaws.com/i/nty8zwujft3ydudvu58m.png
series: Ionic Framework & Firebase React Hooks
---

> Please checkout and subscribe to my video content on YouTube. Feel free to leave comments and suggestions for what content you would like to see. 
[YouTube  Channel](https://www.youtube.com/channel/UCMCcqbJpyL3LAv3PJeYz2bg)

### Overview 
Simple application with a list of things and the ability to add, edit and delete things. We will use the `useReducer` hook to manage the state of the array of things.

We will use the `useState` hook to manage the state of the modal dialog we are using to input the information for the thing we are editing or updating and we use the `useState` hook to manage the state of the input field in the modal dialog.

## Lets Start with the useReducer API
```javascript
// useThings.js
// --
import React from "react";

const useThings = () => {
  // handle the specific action dispatched
  const reducer = (state, action) => {
    switch (action.type) {
      case "ADD_THING": { }
      case "DELETE_THING": { }
      case "EDIT_THING": { };
      default: {
        return state;
      }
    }
  };

  // here we set things up to use the reducer
  const [state, dispatch] = React.useReducer(reducer, {
    things: []
  });

  // the function returns everything needed to the caller to
  // dispatch specific action and get the updated state changes
  return {
    state,
    dispatch
  };
};

export default useThings;
```
### Modify values in the state
**Add An Item:** Add the `action.data` to the end of the array, set state properties
```javascript
case "ADD_THING": {
  return { ...state, things: [...state.things, action.data] };
}
```
**Deleting An Item:** Add the `action.index` slice the array to get the things before the thing specified by the index and everything after the item specified by the index. This in turn is used to create new array which we set `state.things` with
```javascript
case "DELETE_THING": {
  return {
    ...state,
    things: [
      ...state.things.slice(0, action.index),
      ...state.things.slice(action.index + 1)
    ]
  };
}
```
**Editing An Item:** Add the `action.index` slice the array to get the things before the thing specified by the index and everything after the item specified by the index. Next we use the `action.data` as the new element to replace the element that was previously there. This in turn is used to create new array which we set `state.things` with.
```javascript
case "EDIT_THING": {
  return {
    ...state,
    things: [
      ...state.things.slice(0, action.index),
      action.data,
      ...state.things.slice(action.index + 1)
    ]
  };
}
```

## Displaying a Modal for User Input

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/drmn0kvamdgvedgnuz9c.png)

Using the `useState` functionality to manage displaying the modal
dialog for inputting data for new things or editing things. The state has two keys, `isVisible` and `value`. `isVisible` will be set to true to show the dialog and false to hide it. The `value` property will be set when we are actually editing an object. We will also add an additional property called `index` when editing a thing so we can find it in the state array to update it.
```javascript
// ThingsList.js
// --
// using the useState functionality to manage displaying the modal
// dialog for inputting data for new things or editing things
const [modalInfo, setModalInfo] = useState({ isVisible: false, value: "" });
```
## Managing the Input Value Using useState

```javascript
// ThingEdit.js
// --
const [inputValue, setInputValue] = useState();
```
How we use this in the `render` method of the component; when there is an input event in the input element, we update the state with the value entered by the user
```jsx
<IonInput
  value={inputValue}
  onInput={e => setInputValue(e.target.value)} />
```
So when the user is finished in the modal they will click on of two buttons to call the `handleClick` method
```jsx
<IonButton onClick={() => handleClick(true)}>Save</IonButton>
<IonButton onClick={() => handleClick(null)}>Cancel</IonButton>
```
If `handleClick` is called with a `true` value, then we need to return the value from the input form which is saved in our state, if the value is passed to `handleClick` is null, then we just need to exit the function and not return any data
```javascript
// ThingEdit.js
// --
const handleClick = _save => {
  handleFormSubmit({ isVisible: false, value: _save && inputValue });
};
```
Back in the `ThingsList` component we need to handle the call from the `ThingEdit` component to process the data received from the modal.

Get the response from the modal/form so we can update or create a new item. if the `_formResponse.value` is empty then ignore because the user selected the cancel button.

If there is a `_formResponse.value` & `modalInfo.index` has a value, then
edit the item; the `modalInfo.index` variable tells us which item in t he array to update;  if no `modalInfo.index` then create a new things with the `_formResponse.value`
```javascript
// ThingsList.js
// --
const handleFormSubmit = _formResponse => {
  if (_formResponse.value) {
    modalInfo.index != null
      ? editEntry(modalInfo.index, _formResponse.value)
      : addNewEntry(_formResponse.value);
  }
  // reset the modalInfo state
  setModalInfo({ ...modalInfo, isVisible: false, value: "" });
};
```
## Displaying the List Of Things

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/5rup1puza36vxrzzxts2.png)
Rendering the list of things from the components custom hook, `useThings`, we mentioned at the start of the post.
```javascript
// get the function from my custom hook to mange the list
// of things
let { state, dispatch } = useThings();
```
This give us access to the state object and the state object contains `state.things`. We loop through the array of values using the `Array.map()` function

```jsx
<IonList>
  {state.things.map((_thing, _index) => (
    <IonItem key={_index}>
      <IonLabel className="ion-text-wrap">{_thing}</IonLabel>
      <IonButton onClick={() => modalInfoWithEntry(_thing, _index)}>
        Edit
      </IonButton>
      <IonButton color="danger" onClick={() => deleteEntry(_index)}>
        Delete
      </IonButton>
    </IonItem>
  ))}
</IonList>
```
We have all of the base function that are wrappers for calling the reducer methods with `dispatch`

```javascript
// ThingsList.js
//- 
 
/**
 * add entry to the list using `dispatch` from custom hook
 */
const addNewEntry = _data => {
  dispatch({ type: "ADD_THING", data: _data });
};

/**
 * remove entry from the list using `dispatch` and index in the array
 * to call custom hook
 * @param {*} _index
 */
const deleteEntry = _index => {
  dispatch({ type: "DELETE_THING", index: _index });
};

/**
 * update an existing entry in the list based on data
 * and the index of the entry
 * @param {*} _index
 * @param {*} _data
 */
const editEntry = (_index, _data) => {
  let payload = { index: _index, data: _data };
  dispatch({ type: "EDIT_THING", ...payload });
};

```

## Wrapping It All Up
All of the code for this projects in available to you here in the CodeSandbox.io website listed below.

React hooks with `useState` and `useReducer` allows for your whole application to just be functional components who's state can be managed with the hooks api.

Here is a link to a great video to give you some of the reasons why you might want to give hooks a try in your application.
{% youtube eX_L39UvZes %}



{% codesandbox tovwv %}