Necessary configure for create-react-app with redux, react-redux, redux-thunk, react-router, react-router-dom, sass, code spliting, jQuery, bootstrap, react-loadable, react-scrollchor, react-intl, react-select, react-datepicker, react-table, moment, ...
- Start with
create-react-app
- Config environment variables
- Post-Processing CSS:
- CSS Preprocessor (Sass, Less, etc.)
- Create Node.JS server
- Environment for react app
- Organize
src
react app - jQuery
- Bootstrap 3, 4
- Font Awesome
- Animate.css
react-router-dom
(router)react-loadable
(code-splitting)react-intl
- API to format date, number and string- Redux:
redux, react-redux, redux-thunk
- Fetch Data API to server node
- UI Awesome with React Component
- Datatable with
react-table
- VS Code Extensions
- VS Code User Settings
In this step, you should have create-react-app
is installed globally.
- Create a new app:
create-react-app react-app
- use
npm start
oryarn start
to start development - use
npm build
oryarn build
to build production
In this tutorial, I will use yarn
, you can also use npm
.
Create environment files, create-react-app
will use them.
- In terminal at root:
touch .env .env.development .env.production
- In
.env.development
:REACT_APP_ENV=development
- In
.env.production
:REACT_APP_ENV=production
You can also set new environment variable.
Note: only variable with prefix REACT_APP_
can use in create-react-app
As create-react-app
said:
This project setup minifies your CSS and adds vendor prefixes to it automatically through Autoprefixer so you don’t need to worry about it.
- In terminal:
yarn add node-sass-chokidar npm-run-all
- In file
package.json
:
{
"scripts": {
- "start": "react-scripts start",
- "build": "react-scripts build",
+ "start": "npm-run-all -p watch-css start-js",
+ "build": "npm-run-all build-css build-js",
+ "start-js": "react-scripts start",
+ "build-js": "react-scripts build",
+ "watch-css": "npm run build-css && node-sass-chokidar src/ -o src/ --watch --recursive",
+ "build-css": "node-sass-chokidar src/ -o src/",
}
}
- In file
.gitignore
:
# auto generated files (sass, less, ...)
src/**/*.css
Optional if you need a node.js server
mkdir server
cd server
express
- Rename
app.js
toserver.js
- Join
server.js
and./bin/www
- Move
server.js
to root app - Insert dependencies in
package.json
(which is generated byexpress
) topackage.json
in root (which is generated bycreate-react-app
) - Remove dependencies not use (
serve-favicon
,jade
,ejs
, etc.) - Remove all file in
server
, exceptroutes/index.js
- Correct and customize file
server.js
yarn
For development, use package cors
to cross localhost:3000
(client-side, is react app) to localhost:4200
(server-side, is node express)
yarn add cors
yarn start
or npm start
: start client side (react): localhost:3000
node server
: start server-side (node express): localhost:4200
In development, because we use node server at port 4200, but client side is port 3000, so we should check out environment variable REACT_APP_ENV
(which created in above steps) to fetch data from the server.
- Create environment files: In your terminal:
mkdir src/environments
cd src/environments
touch env.development.js env.production.js index.js
- Edit the files as source code.
baseUrl
is url to server.
Create styles
in src/
to contain variables, mixins, classes, common styles, or theme, etc. for your app:
+ _variables.scss
: declare variables for style.
+ _mixins.scss
: declare mixins for style
+ _classes.scss
: declare some util classes for style
+ index.scss
: import _
files to this file, you should move index.scss
(in root) to this folder and in index.js
, you only import ./styles/index.css
+ You also override some theme (such as AdminLTE, Bootstrap, Material, Angular, Datatables, Charts, ...) with files _
and import to index.scss
Create lib
in src
to contain some library or package you use in this app, or config something with these packages (such as jQuery, Bootstrap, Font-Awesome, Ionicons, Material, ...):
+ You also create index.js
in lib
to import these files in folder.
+ In index.js
in root, you only import by one line: import './lib';
Create services
to contain your services for app. Guides are below sections
Create actions
, reducers
to do with redux
. Guides are below sections
Create components
to contain components in app:
Guides for these components is below sections
- Create
layout
incomponents
to contain layout of app (flow). - Your
App.js
,App.scss
also in here, which importHeader
,Footer
,Sidebar
,Menu
,Body
,... for Navigations and Router
Create common
in components
to contain some components which are used a lot of times. Such as Loading
, Modal
, Alert
, Notification
, Box
, ...
Create pages
in components
to contain some pages in app, which is route in component Body
, such as Home
, Dashboard
, Profile
, Form
, Terms of Service
, Support
, Page not found
, Error page
,...
- In terminal:
yarn add jquery
- In terminal:
touch src/lib/jquery.js
- Edit created file by the following lines:
import $ from 'jquery';
// config jquery variables for other lib use jQuery (such as bootstrap)
window.$ = $;
window.jQuery = $;
- In
lib/index.js
, import by:import './jquery';
- In
index.js
at root,import './lib';
(if you don't have). - In the component, to use jQuery, you should import:
import $ from 'jquery';
- To use jquery function, only use from
componentDidMount()
in Lifecycle React components: - View Demo here
- View Implementation here
componentDidMount() {
// jQuery should declare at here
$(document).ready(() => {
$('#alert').click(() => alert('This is alert be jQuery'));
});
}
Not use jQuery if it's not needed
- In terminal:
yarn add bootstrap
(add @version you choose) - In terminal:
mkdir src/lib
(if you havelib
, skip this step) - In terminal:
touch src/lib/bootstrap.js
- Edit created file as lines (In this tutorial, I use bootstrap 4):
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap/dist/js/bootstrap.bundle.min.js';
- In
lib/index.js
, import by:import './bootstrap';
- In
index.js
at root,import './lib';
(if you don't have). - In the component, you can use bootstrap 3, 4 as document available
- View demo with component
DemoBootstrap
. - View Demo here
- View Implementation here
- In terminal:
yarn add reactstrap@next
- Only import Component to use as reactstrap document
- View demo with component
DemoReactstrap
. - View Demo here
- View Implementation here
- I think you should use
reactstrap
if you want to use some component in react, with event handlers. - If you need some style in bootstrap, you can use directly and don't need to use
jQuery
You can include via file index.html
in folder public
via CDN
or download and link stylesheet
- In terminal:
yarn add font-awesome
- Create file
lib/font-awesome.js
and add lineimport 'font-awesome/css/font-awesome.min.css';
- In
lib/index.js
, import by:import './font-awesome';
- In
index.js
at root,import './lib';
(if you don't have).
yarn add animate.css
- In
lib/
create fileanimate-css.js
and addimport 'animate.css';
- In
index.js
, also import by lineimport './animate-css';
- Custom duration of animation by file scss config in
style/
: - Create file
_animate.scss
as source code - In
index.scss
:@import './animate.scss';
- This file will create classes style to custom time duration:
.animated.duration-100
.animated.duration-200
...
.animated.duration-1100
.animated.duration-1200
...
.animated.duration-3000
Example:
<!-- In/Out default -->
<div class="animated slideInUp">ABCDEFGHIJKLMNOP</div>
<div class="animated slideOut" >ABCDEFGHIJKLMNOP</div>
<div class="animated fadeInDown" >ABCDEFGHIJKLMNOP</div>
<!-- In/Out custom duration -->
<div class="animated fadeInUp duration-500" >ABCDEFGHIJKLMNOP</div>
<div class="animated flipIn duration-1000" >ABCDEFGHIJKLMNOP</div>
<div class="animated slideOutDown duration-700" >ABCDEFGHIJKLMNOP</div>
<!-- Infinite default/custom duration -->
<div class="animated flash infinite" >ABCDEFGHIJKLMNOP</div>
<div class="animated flash infinite duration-1200" >ABCDEFGHIJKLMNOP</div>
- View demo at component
DemoAnimateCss
- View Demo here
- View Implementation here
react-router-dom
is used for route Single Page Application (SPA), not loading again page.
-
In terminal:
yarn add react-router-dom
-
You can view implement in
components/layout/body
-
You also view implement in
components/pages/demo-react-router
-
The Document is available at React Router Dom
react-loadable
is useful for code-splitting:
- Lazy load components until it's called by user, it speeds up your Single Page App (SPA).
create-react-app
will bundle a new script file, when it's called, it will import this file to app.
- In terminal:
yarn add react-loadable react-router-dom
- Create Loading component (view components/common/loading/)
- When use Loadable with loading component, it will add props to this component, such as:
{ isLoading: true, pastDelay: false, timedOut: false, error: null }
- View
components/page/demo-loadable-component
to sample implement. - Component
DemoLoadableComponent
(is not loadable) andLoadableDemoComponent
(is loadable)
- Inspect element in the browser
- Choose tab network
- Click filter JS
- Refresh page
- First only
bundle.js
and some js file - Click component which loadable, you see
*.chunk.js
is loaded. That is lazy loading component - View Demo here
- View Implementation here
Internationalize React apps. This library provides React components and an API to format dates, numbers, and strings, including pluralization and handling translations.
- Display numbers with separators.
- Display dates and times correctly.
- Display dates relative to "now".
- Pluralize labels in strings.
- Support for 150+ languages.
- Runs in the browser and Node.js.
- Built on standards.
You can view the document here: https://github.com/yahoo/react-intl
- In
index.js
, we import and use provider for App component:
import { IntlProvider } from 'react-intl';
ReactDOM.render(
<Provider store={store}>
<IntlProvider locale="en">
<App />
</IntlProvider>
</Provider>,
document.getElementById('root')
);
- In specific component, you can import component of
react-intl
to use. You can view 1 demo about this in demo redux with format date.
yarn add redux react-redux redux-thunk
-
In
src
, create dir and files:actions/action-types.js
: declare action name as constactions/index.js
: declare actions for reduxreducers/
: declare reducersreducers/[name].js
: declare action for a specific object.reducers/index.js
: to combine reducer with redux, after that is to createStore.
-
In
index.js
:import { Provider } from 'react-redux';
: use Provider to store reduximport { createStore, applyMiddleware } from 'redux';
: use createStore and middlewarethunk
with createStoreimport thunk from 'redux-thunk';
: middleware for createStore, support async functionimport allReducers from './reducers';
: reducers after combinedconst store = createStore(allReducers, applyMiddleware(thunk));
: createStore with combined reducer, and apply middleware thunk- You don't care about other reducers, such as
Users
-
In
reducers/index.js
: combine reducers:- In this tutorial, I demo with Items and Users (users is used for other section demos).
import { combineReducers } from 'redux';
import Items from './items';
import Users from './users';
const reducers = combineReducers({
Items,
Users
});
export default reducers;
mkdir src/services
(if you have not)touch db-service.js auth-service.js
(db- to get database, auth- to authentication user)- Example with
db-service.js
:import Env from './../environments';
: to getbaseUrl
with environmentsexport default class DbService
as static class- set baseUrl to get API:
static baseUrl() { return Env.baseUrl; }
static parseUrl(url) { return DbService.baseUrl() + url; }
Example get
API:
static getItems = () => {
let url = DbService.parseUrl('/api/items');
console.log(url);
return fetch(url).then(res => res.json());
}
Example Post
API:
static addItem = (item) => {
let url = DbService.parseUrl('/api/items');
return fetch(url, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(item)
}).then(res => res.json());
}
Animation to show component when user scroll to view.
yarn add react-reveal
Fade
Flip
Rotate
Zoom
Bounce
Slide
Roll
left/right/top/bottom
fadeOut
Jump
Flash
HeadShake
Jello
Pulse
RubberBand
Shake
Spin
Swing
Tada
-
View demo with component
DemoReactReveal
.
Animation to scroll to a component when user clicks to the link.
yarn add react-scrollchor
-
View demo with component
DemoReactScrollchor
.
- View demo for this guide here: Demo
- View implementation in
demo-react-table
- Implementation - In this guide, we use
react-table
with features:- Lightweight at 11kb (and just 2kb more for styles)
- Fully customizable (JSX, templates, state, styles, callbacks)
- Client-side & Server-side pagination
- Multi-sort
- Filters
- Pivoting & Aggregation
- Minimal design & easily themeable
- Fully controllable via optional props and callbacks
- In this guide, we also use
react-select
andreact-datepicker
withmoment
. You can view docs for these packages here:
I think the following extensions are helpful for development:
- ES7 React/Redux/GraphQL/React-Native snippets
- JavaScript (ES6) code snippets
- Bootstrap 3 Snippets
- Bootstrap 4 & Font awesome snippets
- Font-awesome codes for html
- Font-awesome codes for css
- HTML Snippets
- HTML CSS support
- npm
- npm Intellisence
- Path Intellisense
- SCSS IntelliSence
- Auto Close Tag
- Auto Rename Tag
- IntelliSense for CSS class names
- Prettier - Code formatter
- EditorConfig for VS Code
- ESLint
- TSLint
- Sass
- Sass Formatter
- Beautify css/sass/scss/less
I think you also setting your VSCode by following steps:
- Enter
Ctrl + Shift P
- Search
user settings
- Choose
Preferences: Open User Settings
and enter. - Edit your file
User Settings
by following lines: (you can search inDefault Settings
and customize your style)
{
"workbench.iconTheme": "vscode-icons",
"workbench.startupEditor": "newUntitledFile",
"window.zoomLevel": 0,
"editor.fontSize": 13,
"eslint.autoFixOnSave": true,
"tslint.autoFixOnSave": true,
"editor.formatOnSave": false,
"editor.renderWhitespace": "boundary",
"editor.quickSuggestions": {
"other": true,
"comments": true,
"strings": true
},
"terminal.integrated.cursorStyle": "line",
"terminal.integrated.fontSize": 13,
"terminal.integrated.fontFamily": "",
"vsicons.projectDetection.autoReload": true,
}