React Components:
-
Use
PureComponent
instead ofComponent
. -
For stateless Components, wrap them with
React.memo()
orRecompose.pure()
. -
Break big Components into pieces, wrap static pieces (part that doesn't use props or state) with
React.memo
orRecompose.pure
, it shall avoid re-render as much as possible. -
Only Layout Components and Page Components are aware of store from Redux.
-
All common Components should only work on it own props and are not aware of the app store (so you can reuse it with other app).
-
Ideally, all components should aware of the data it gonna use, so we just give the component only the data it needs.
-
All components need very details propTypes, especially
.shape()
(with meaningful commenting) -
Avoid using props.something as much as possible if not totally, always declare const { something } = props in the beginning of function as it is very intuitive and easier to track what props of props you gonna use.
-
Never use inline function eg.
onChange={() => ... }
, that anonymous function will trigger the component re-render all the time, it will be very bad in term of performance especially when using them (inline functions) with a complex and expensive Component. -
Same strategy with object and array, avoid using
something={[...]}
orsomething={{...}}
, component will received the new object/array all the time. Even avoid using method that will return new object/array eg.getSomething() { return [ ... ] }
thenaProp={getSomething()}
, that will be the same as declaring inline object/array. Instead,getSomething
should be a reselect selector.getSomething = defautMemoize(function(param) { return [] })
.
Redux:
-
Only root Component (App) you can bind all store state.
-
Other non-root Components you should only give Components the data they only needs (use mapStateToProps wisely).
-
Use reselect as much as possible (if not always) for mapStateToProps.
Reselect:
-
You can create a dedicate directory with contain all common selectors and use that when you want.
-
In reselect, only give the selector data it need, use reselect parameters wisely as reselect parameter will affect reselect performance.
Router:
- Attach Router (withRouter) to root Component and any specific Component which need Router only.
Other:
- Never mutate objects, arrays, funcs instead of replace them with the new one. The main benefits of replacing (non-mutation) is to determine the data state is changed or not, and it will make an expectable circumstance. If you mutate an object, it is very hard to know whether the object has something change because it is still the old object and object reference. If the object has no change so just do nothing, but if the object has something changed, we should return a new object to tell the program that I have some changing and you should do some shallow comparison. Only mutate when you have no choice. Mutate also makes object referencing is kind of confusing and messy.