This repo is for the purposes of a high-level view of React architecture and best practices. As this repo grows, more ideas will be introduced and comparisons will be made with pros and cons.
Being that this is a public repo, I hope that people will not only take what they can from the repo's information, but contribute as well. Feel free to submit pull requests and I will add your information to the document.
Forking this repo is great if you want to create your own repo with your decisions, using this as a starting point.
Updated 1-27-19
The repo has taken a narrowed down form from everything suggested to what I'm using in my own projects. This is a vetting process and what you see here is what I eventually chose.
To keep this as a good reference template (or guide), I'm going to keep this narrow approach. If you have any differing opinions, let me know as an issue! Or feel free to fork this document and insert your own conclusions.
Flux Pattern
https://code-cartoons.com/a-cartoon-guide-to-flux-6157355ab207
Render Props Pattern
https://medium.freecodecamp.org/how-to-develop-your-react-superpowers-with-the-render-props-pattern-b74e68c6d053
- Immutability
- No side-effects
- Predictable data
- Functional methods
- map/filter/reduce
- Higher Order Components/Functions
- Reusability and Composition
- fn(state, props) == UI
- Local state suggestions from: https://medium.com/@robftw/characteristics-of-an-ideal-react-architecture-883b9b92be0b
- No local state other than:
- Animation/triggering of CSS Classes
- UI control that doesn't involve business logic or dependent on other components
- Extremely trivial UI related variables that won't cause side effects
- Standalone libraries
- No local state other than:
React Router
https://github.com/ReactTraining/react-router
Guide:
https://reacttraining.com/react-router/web/guides/quick-start
Redux
https://redux.js.org/
Redux DevTools
Chrome Extension
This is a must have for Redux development.
Great article if you want to hone your skills:
https://codeburst.io/redux-devtools-for-dummies-74566c597d7
Redux Thunk
https://github.com/reduxjs/redux-thunk
"Thunks are the recommended middleware for basic Redux side effects logic, including complex synchronous logic that needs access to the store, and simple async logic like AJAX requests."
Redux-Sagas
https://github.com/redux-saga/redux-saga
Similar concept to thunk using Middleware to control side-effects in a React-Redux application, but with the added bonus of using ES6 Generators to control async flow and increase readability.
From: https://redux.js.org/recipes/structuring-reducers/normalizing-state-shape
Normalized data structures by Id (Relational Table Model)
{
posts: {
byId: {
"post1" : {
id: "post1"
author: "author1"
body: "..."
comments: ["comment1", "comment2"]
},
"post2" : {
id: "post2"
author: "author2"
body: "..."
comments: ["comment3", "comment4", "comment5"]
},
},
allIds: ["post1", "post2"],
},
comments: {
byId: {
"comment1": {
id: "comment1",
author: "user2",
comment: "...",
},
"comment2": {
id: "comment2",
author: "user3",
comment: "...",
},
"comment3": {
id: "comment3",
author: "user3",
comment: "...",
},
"comment4": {
id: "comment4",
author: "user1",
comment: "...",
},
"comment5": {
id: "comment5",
author: "user3",
comment: "...",
},
},
allIds: ["comment1", "comment2", "comment3", "comment4", "comment5"],
},
users: {
byId: {
"user1": {
username: "user1",
name: "User 1",
},
"user2": {
username: "user2",
name: "User 2",
},
"user3": {
username: "user3",
name: "User 3",
},
},
allIds: ["user1", "user2", "user3"]
},
simpleDomainData1: {...},
simpleDomainData2: {...},
}
Removes the deeply nested structures as your state grows in size and keeps components from re-rendering accidentally.
.
├── /android/
├── /ios/
|
├── /assets
│ ├── /fonts/
│ ├── /images/
│ ├── /videos/
|
├── /app or /src
│ ├── /ducks/ // See "Ducks"
│ ├── /scenes/
│ | ├── /App
│ | | ├── /_/
│ | | ├── /App.js
│ | | └── /index.js
| | ├── /MyScene/
| | | ├── /__tests__/
| | | ├── /_
| | | | ├── /MySubcomponent
| | | | ├── /__tests__/
| | | | ├── /MySubcomponent.js
│ | | | └── /index.js
│ | | ├── /MyScene.js
│ | | └── /index.js
│ ├── /shared/
| | ├── /SharedAppSpecificComponent
| | ├── /__tests__/
| | ├── /SharedAppSpecificComponent.js
| | └── /index.js
│ └── /types/
|
|
├── /lib
| ├── /Button
| ├── /__tests__/
| ├── /Button.js
| └── /index.js
|
├── /tools/ //Build scripts, other tools
├── /node_modules/
└── package.json
/lib/ explanation: Every component that is not "app specific" or a primitive component can be a candidate to be moved to the /lib/ folder. This allows for the possible side effect of hand-rolling your own component library as you code!
Primitive components are those that take in only primitives as their props and are functionally pure.
.
├── /ducks/
└── /MyDuck/
| ├── /__tests__/
| ├── /models // See redux-orm
| | ├── index.js
| | ├── MyDuckModel1.js
| | └── MyDuckModel2.js
| ├── actions.js
| ├── index.js
| ├── reducers.js
| ├── selectors.js
| ├── types.js
| └── utils.js
├── rootReducer.js
├── orm.js // See redux-orm
└── commonTypes.js
https://medium.freecodecamp.org/scaling-your-redux-app-with-ducks-6115955638be
From: https://hackernoon.com/react-components-naming-convention-%EF%B8%8F-b50303551505
[Domain]|[Page/Context]|ComponentName|[Type]
Examples:
ACommunityAddToShortListButton - [Domain][ComponentName][Type]
SideBar - [ComponentName]
SideBarSwitch - [ComponentName][Type]
ChatConversation - [Page/Context][ComponentName]
ChatConversationName - [Page/Context][ComponentName]
- Write a stateless functional component first
- if (component requires state or life-cycle) Make stateful class
- if (component is comprised of multiple components or smaller pieces of functionality) Create container component
- Move shared components out
- if (app dependent) Keep in shared/MyComponent
- if (!app dependent or primitive) Move to lib folder
- Avoid re-rendering component if possible
Semantic UI React
https://github.com/Semantic-Org/Semantic-UI-React
A JQuery-free version of Semantic UI that comes with React-based components. Semantic UI is great for themeing as well.
Jest
https://jestjs.io/
Most popular React testing library. Comes with snapshot comparisons which is very useful for testing pure components.
Sinon
https://sinonjs.org/
Spies, stubs and mocks
Cypress
https://www.cypress.io/
Testing suite that provides a click-and-check API for automated in-browser smoke tests.
From: https://github.com/kylpo/react-playbook/blob/master/best-practices/react.md
Write component tests that accomplish the following goals (from Getting Started with TDD in React)
- It renders
- It renders the correct thing
- Default props
- Varied props
- It renders the different states
- Test events
- Test edge cases
- e.g. something that uses an array should be thrown an empty array
https://reactjs.org/community/starter-kits.html
This list contains many popular choices, but your choice is yours. Getting a good starter kit depends entirely on what you're looking to get out of your project and team.
Babel
https://babeljs.io/
Transpiles your javascript down from the latest standards to backwards compatible, browser friendly source. Used for transpiling JSX to JS.
Webpack
https://webpack.js.org/
Bundles your files into static assets that are ready for production deploy. Many extensible plugins available.
ESLint
https://eslint.org/
Keeps your code nice and tidy by yelling at you with squigglies. You can link this to your IDE.
Great ESLint configs:
prettier-eslint
eslint-config-airbnb
From: http://www.guyroutledge.co.uk/blog/git-branch-naming-conventions/
type/component-name/title
Common Types:
- feature
- fix
- hot-fix
- refactor
- update
- upgrade
- remove
Component Name example:
login-form
Title example:
hoc-formik-input
Formik
https://github.com/jaredpalmer/formik
Creates an ephemeral state held by its components that abstracts away all the boilerplate that goes into creating and maintaining forms.
Reselect
https://github.com/reduxjs/reselect
Creates a selector where the first functions passed in compute props for a final function. If none of those props have changed, then that function is not run and the result from the previous invocation is returned.
This keeps the state from needlessly causing components to re-render.
redux-orm https://github.com/tommikaikkonen/redux-orm
Library that creates Object Relational Mapping (ORM) using the aforementioned structure.
Guide to using redux-orm and Redux structuring as a whole:
https://blog.isquaredsoftware.com/series/practical-redux/
Recommended Course:
Practical Redux Course by Mark Erikson
classnames
https://github.com/JedWatson/classnames
Takes in conditionals that returns a space-delimited string for className.
import classnames from 'classnames';
let classes = classnames('sd-date', {
current: date.month() === this.props.month,
future: date.month() > this.props.month,
past: date.month() < this.props.month
});
return (
<button className={classes} />
vs
<button className={`button-default-style ${isActive ? "active" : ""}`} />
);
Recompose
https://github.com/acdlite/recompose
A library of Higher-Order-Functions and a compose function to ease your move towards more reusable, functional components.
Note: This library is no longer being updated with new features by its creator. With Hooks on the horizon, the React Development team is suggesting a move to that API.
date-fns
https://date-fns.org/
Date/Time formatting with a functional paradigm and localization.
Visual Studio Code
https://code.visualstudio.com/
Microsoft has opensourced this light-weight and highly extensible IDE. My personal favorite.
Atom
https://atom.io/
Another IDE that is also very popular amoung web devs.
Webstorm
https://www.jetbrains.com/webstorm/
A JetBrains product who also make IntelliJ and ReSharper. It's not free, but has a mix of monthly and yearly subscription options for the license.
React 16.x
https://reactjs.org/blog/2018/11/27/react-16-roadmap.html
Things to look forward to:
- Suspense
- Fallback component while a component is rendering. E.g. abstracts need for loading gifs.
- Hooks
- Add state to function components. Improves optimizing at scale and removes need for "wrapper hell"
- Concurrent
- Prioritize renders
React Native Radio w/ Nadir Dabit
https://devchat.tv/react-native-radio/
Syntax w/ Wes Bos and Scott Tolinski
https://syntax.fm/
The React Podcast w/ Chantastic
https://reactpodcast.simplecast.fm/
freeCodeCamp
https://www.freecodecamp.org/
HackerNoon
https://hackernoon.com/
React.js Newsletter
http://reactjsnewsletter.com/
Good Starting Points:
https://github.com/markerikson/react-redux-links
Folder Structure
https://github.com/kylpo/react-playbook/blob/master/component-architecture/3_Multiple-Components.md
Presentational vs Container Components
https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0
Routing
https://medium.com/@algfry12/react-router-best-practices-9c564388f4d3