Hello dear dev.to,
Iam working for instant-data. 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 on github.
In this i follow the ducks pattern, in which you try to keep all your redux and store reducer stuff in one single file, 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 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:
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.
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:
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
<MuiThemeProvider theme={createMuiTheme()}>
//any content here
</MuiThemeProvider>
read more about Material UI 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
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
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.
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.
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
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: :-)
Top comments (0)