Counter application with react and typescript
Tags: react, typescript, hooks, counter
Published: 2021-11-13 05:37:48

Let's build this counter application using react-typescript.We are going to use `useReducer` hook for this application.

![This is a counter application picture](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l88b1oyrq4q9hep3cjfo.png)

Let's set up our application

```
$ cd Desktop
$ mkdir react-counter
$ cd react-counter
```

Now create a react app

```
$ npx create-react-app ./ --template typescript
```

You should see a brand new react application.Clean up all unnecessary files.You can use a different component but in my case i am going to use App.tsx component.

At first create a component App and export it defaultly

```javascript
const App:React.FunctionComponent=()=>{
  return <div className='container'></div>
}
```
Now we are going to setup our useReducer hooks.Add this statement to your code 

```javascript
const [state, dispatch] = React.useReducer(counterReducer, initialState);
```
Now let's create our cunterReducer and initialState

First initialState..

```javascript
const initialState = {
  count: 0,
};
```
And then counterReducer

```javascript
type ActionsType = {
  type: string;
  payload?: number;
};

const counterReducer = (
  state: typeof initialState,
  action: ActionsType
): State => {

};
```

Now let's add some actionTypes and actionCreators

ActionTypes..

```javascript
const INCREMENT = "INCREMENT";
const DECREMENT = "DECREMENT";
const RESET = "RESET";
```
and  actionCreators..

```javascript

const increment = (value: number) => {
  return {
    type: INCREMENT,
    payload: value,
  };
};

const decrement = (value: number) => {
  return {
    type: DECREMENT,
    payload: value,
  };
};

const reset = () => {
  return {
    type: RESET,
  };
};

```
Yeah i am using redux pattern.Now let's add some logic to our reducer.

```javascript
 switch (action.type) {
    case INCREMENT:
      return { ...state, count: state.count + Number(action.payload) };
    case DECREMENT:
      return { ...state, count: state.count -Number(action.payload) };
    case RESET:
      return { ...state, count: 0 };
    default:
      return state;
  }
```
Now let's add some jsx to our application

```html
<div className="container">
      <p>{state.count}</p>
      <div className="wrapper">
        <button onClick={() => dispatch(increment(2))}>increment</button>
        <button onClick={() => dispatch(decrement(2))}>decrement</button>
        <button onClick={() => dispatch(reset())}>reset</button>
      </div>
<div>
```
If you want those styles you can add these css code in `index.css` file

```css
p {
  font-size: 2rem;
  font-weight: 600;
}
button {
  background: #004567;
  color: white;
  border: none;
  border-radius: 3px;
  padding: 20px;
  margin: 10px;
  font-size: 1.2rem;
  text-transform: capitalize;
}
.container {
  width: 500px;
  margin: 100px auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

```
If you start your application you should see something on the screen a simple counter application working.

Now add a input element to add numbers randomly..

```html
<input type="number" name="count" value={value} onChange={handleChange}/><button onClick={() = dispatch(increment(value as number))}>
       add
</button>
```
Now where do i get those `value={value}` and `onChnage={handleChange}` for that add following code at top of your component

```javascript
const [value, setValue] = React.useState<number>();
```
and change handler `handleChange`

```javascript
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setValue(Number(e.target.value));
  };
```
you should keep all hooks at the top then functions

Now add these css code for your input element

```css
input {
  padding: 10px;
  width: 300px;
}
```

Now if you got to your browser and refresh if it is needed,you should see same counter application as i have shown you at the top.Try to click buttons and check if it is working.

Thank you for being with me so long.See you.Bye!