reducks, a boilerplate
Tags: typescript, javascript, react, reducks
Published: 2018-09-11 18:27:54

---
title: reducks, a boilerplate
published: true
description: 
tags: #typescript #javascript #react #re-ducks
cover_image: https://images.unsplash.com/photo-1525136955915-d1f6eb2a4f02?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=7dc5d64a57a7dd5c3caa03119cd22147&auto=format&fit=crop&w=2550&q=80
---
[img by Jase Ess](https://unsplash.com/@jaseess)

# Hello dear dev.to,

Iam working for [instant-data](http://www.instant-data.com/). a small company that provides solutions in the environment of a larger advertising agency. mostly internal toolings.

After playing round a little with the create-react-app, i wanted to share my latest boilerplate with you and ask for your opinions, or improvements. You can visit me  [here](https://github.com/janpauldahlke/react-ts-boilerplate-2018/) on github.
In this i follow the ducks pattern, <b> in which you try to keep all your redux and store reducer stuff in one single file</b>, but for sakes of DRY, i will present you the README.MD. I appreciate any feedback ;-)

It is created via the CLI-Tool ```create-react-app <your-appname> --scripts-version=react-scripts-ts``` and customized to my needs, by running ```npm eject```

### Prequisites

Installed node and npm Version 8 or higher.

## Available Scripts

In the project directory, you can run:

#### `npm start`

Open [http://localhost:3000](http://localhost:3000) to view it in the browser.


#### `npm run build`

Builds the app for production to the `build` folder.

#### `npm run seed` Authentication seed

To make the boilerplate work from scratch, and to simulate the flow of Auth, we put a JSON-Server.
You should remove the complete seed folder, or better add it to your `.gitignore`, when you implement your own workflow. To make use of it simply `npm run seed`. You will get served at `json-server --port 4000 --watch -- seed/db.json`.


#### Folder Structure

After creation, your project should look like this:

```http://www.instant-data.com/
my-app/
  README.md
  node_modules/
  package.json
  public/
    index.html
    favicon.ico
  seed/
    /* a helper fake backend for firsttimers */  
  src/
    index.tsx
    components/
      App.tsx
    containers/
      /* your connected containers here */
    ducks/
      /* your ducks here */
    services/
      /* put all your global helpers inside here */
    store/
      history.ts
      index.ts
      localStorage.ts
  types/
    /*your types go here */  
```

#### Debugging and DevTools

I strongly suggest you to install and use theses BrowserExtensions.  
* [redux-devtools](https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd)
* [react-devtools](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi)

#### Material-UI and Decorators

The experimental feature for Decorators is activated in the `tsconfig.json`. By this it is possible to use the withStyle decorator in combination with `compose` of the `recompose package`. 
Example usage is:

```javascript
import { compose } from 'recompose';
import { withStyles } from '@material-ui/core/styles';

@(compose(withStyles(styles)) as any)
class Example extends React.Component<IExampleProps, IExampleState> {...}
```

To make use of themes in material-ui we need to wrap the content of App inside a
```javascript
<MuiThemeProvider theme={createMuiTheme()}>
  //any content here
</MuiThemeProvider>
```
[read more about Material UI Themes](https://material-ui.com/customization/themes/)


### Environment

There is the possibility to provide ENV variables. use the `.env` file for this.
Please note, they need to follow the naming convention of `REACT_APP_` `EXAMPLE=FOOBAR`.
Inside the project one can consume them by `proccess.env.REACT_APP_EXAMPLE`. 
At a new start its set to the seedings path, so one might want to change it there.


### HTTP Requests

Please use axios for your requests. It supports Promises and also async/await.
[https://github.com/axios/axios](https://github.com/axios/axios)
Also make sure the allow crossorigin-access on your server.


### Ducks

We follow the 'Ducks'-Pattern to structure our application. Get insights on this specc here
[https://github.com/erikras/ducks-modular-redux](https://github.com/erikras/ducks-modular-redux) 
The pattern is to have all these inside one duck:

* action enum
* action types
* action creators
* reducer functions
* mainreducer
* thunk
* initialStore


### Message Component

There is a rudimental example prepared in this boilerplate, that shows usage and consumption of a high level message or notification-component. Import the NofictationDuck inside the Ducks that you want the NotificationStore to be catched.

```javascript
import NotificationDuck from '~/src/ducks/notification';

your.action()
  .then(() => /* success */)
  .catch((err) => {
      dispatch(NotificationDuck.throwNotificationWithError({text: 'your text', title: 'your title'}))
  })
  ```
But you can also connect them directly to components. Please keep in mind to reset the NotificationStore, with the `RESET_NOTIFICATION_STORE` action! 


### Store

Use the folder `src/store` to configure the store of redux according to your needs. There is also the possibilty to subscribe parts of the store to your localStorage. To do so check the `index.ts` and have a brief look at the store subscribe pattern.

```javascript
store.subscribe(throttle(() => {
  const storage = store.getState() as RootState;
  const AuthStore = storage.AuthStore;

  saveState({
    AuthStore
  } as RootState);
}, 300));
```
Please make use of the `throttle` lodash-helper. `JSON.parse()/JSON.stringyfy` are expensive in Javascript.

## Services

Anything you want to consume repetitive belongs to the services. Another word could be globalHelpers.  

* apicontroller -> an axois instance the can be configured. import it into your ducks to make `http`-verbs.
* authenticationService -> can be used in conjunction with apicontroller inside of ducks to verify auth-Status

inside your duck - an example usage in thunk
```javascript
import axios from '../../services/apicontroller';

public static getAuth() {
    return function (dispatch: any, getState:() => RootState): Promise<void> {
      dispatch(AuthDuck.getAuthAction());

      //return the axois object with header, pass the state by `getState()` to auth and GET the route with `get('/yourRoute')`

      return axios(getState()).get('/Authentication')
        .then((res) => {
          dispatch(AuthDuck.getAuthSuccessAction(res.data));
         })
        .catch((err: Error) => {
          /**
        });
    };
  }
```

There is also a whole `react-router` v4 part, i will explain at 50 :heart: :-)