Minimalistic React app structure with Redux and React Router
Your machine must already installed:
- NodeJS
- Yarn
- Recommended: Visual Studio Code, Sublime Text
- Recommended extensions for Visual Studio Code:
- Babel: https://marketplace.visualstudio.com/items?itemName=dzannotti.vscode-babel-coloring
- Prettier: https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode
- ESLint: https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint
- Path-autocomplete: https://marketplace.visualstudio.com/items?itemName=ionutvmi.path-autocomplete
Developers must be familiar with:
react
redux
redux-thunk
- create-react-app
- Fetch API
eslint
prettier
yarn install
: Run at first time clone this project or when any module missing.yarn start
: Start project at development mode.yarn build
: Build project to production.
- /src
- index.js
- App.js: Single app root component.
- /constants
- /helpers: Helpers/Utility functions that would be used among modules
- FetchHelper.js: A wrapper for Fetch API
- /redux: All setup for Redux (reducers, store, middlewares)
- /modules: Each module is a feature or re-used components
- /common: A special module which contains many reused components among the app. Some components in here can be separate in to their own module if nessessary.
- /module1: A module may relate to a feature. It contains many components, pages, actions, reducers, services, ... which are highly relate to each other.
- index.js: All module items which are needed to be used from outside need to be export from here. From the outside, avoid to import module item directly.
- /actions: Redux actions
- /components: React components, could be separated into 2 directories: containers and presenters if nessessary.
- /reducers: Redux reducers
- /...: More directories if nessessary.
- /module2
- /...
import FetchHelper from './src/helpers/FetchHelper.js' FetchHelper.addAfterResonseInterceptor(resp => { if (resp.status === 500){ //show error message } if (resp instanceof Error){ //handle error. This is likely caused by the network connection. } })
import FetchHelper from './src/helpers/FetchHelper.js' import {api_root} from './src/constants' FetchHelper.fetch(`${api_root}api/data.json`) .then(([data, status]) => { // 'data' is JSON object. If server does not response JSON then 'data' is Response object. if (status === 200){ //handle data }else{ //show error message } })
Or
async function requestData(){ const [data, status] = await FetchHelper.fetch(`${api_root}api/data.json`) if (status === 200){ //handle data }else{ //show error message } }
import FetchHelper from './src/helpers/FetchHelper.js' import {api_root} from './src/constants' FetchHelper.fetch(`${api_root}api/products`, { method: 'POST', body: JSON.parse({ name: '...', type: '...' }) }).then(([data, status]) => { if (status === 200){ //handle data }else{ //show error message } })
import FetchHelper from './src/helpers/FetchHelper.js' import {api_root} from './src/constants' FetchHelper.fetch(`${api_root}/api/categories`, { method: 'POST', headers: { 'Content-Type': FetchHelper.FORM_URL_ENCODED, }, body: FetchHelper.jsonToForm({ name: '...', type: '...' }) }).then(([data, status]) => { if (status === 200){ //handle data }else{ //show error message } })