Based on: https://reactjs.org/docs/thinking-in-react.html
- Break data model into components that (ideally) only do one thing.
- Break down UI into components, where each component matches one piece of the data model.
- Arrange UI components into a hierarchy.
- Build a static version of the hierarchy in React.
- At this stage, use
props
rather thanstate
(see “What is the difference between state and props”). - Each component should only have a render() method (since it is static).
- Generally, build bottom-up (i.e. low level of heirarchy first) and write tests as you build.
- Data will be input as a
prop
into the top of the hierarchy, e.g. in index.js:ReactDOM.render(<App data="dataSource" />, document.getElementById('root'));
- At this stage, use
- Identify the minimum set of mutable (i.e. changeable) state required by the app.
- Don’t Repeat Yourself Principle
- e.g. it is good for state to reference an array, but not the number of items in the array.
- Three questions:
- Is it passed in from a parent via props? If so, it probably isn’t state.
- Does it remain unchanged over time? If so, it probably isn’t state.
- Can you compute it based on any other state or props in your component? If so, it isn’t state.
- Identify which component mutates, or owns, the state.
- For each piece of state in your application:
- Identify every component that renders something based on that state.
- Find a common owner component (a single component above all the components that need the state in the hierarchy).
- Either the common owner or another component higher up in the hierarchy should own the state.
- If you can’t find a component where it makes sense to own the state, create a new component solely for holding the state and add it somewhere in the hierarchy above the common owner component.
- The owner of the
state
will pass it to components that need it viaprops
. - Components that mutate state should avoid UI rendering.
- For each piece of state in your application:
- Add inverse data flow (i.e. from lower hierarchy to higher).
- Components should only update their own state.
- Pass callbacks (e.g.
onChange
event) from higher components to lower components, which will fire when the state should be updated. - The callbacks will call
setState()
.
Based on: https://reactjs.org/docs/design-principles.html
- The key feature of React is composition of components.
- Components should be able to be changed without affecting the rest of the codebase.
- Components describe any composable behaviour, which includes rendering, lifecycle and state.
- Resist adding features that can be implemented by clients.
- Minimal API Surface Area
- Only add out-of-scope features if it will avoid clients producing multiple solutions to the same problem.
- Before deprecating a feature, always consider all use cases and communicate reasons and alternatives to clients.
- If some pattern is hard to express in a declarative way (“I want a table for two”), provide an imperative API (“Go to restaurant, speak to waiter, etc.)”).
- If you can’t identify a perfect API, provide a temporary subpar API (but it must be temporary).
- Value API stability.
- When something changes, there should be a clear (and preferably automated) migration path.
- Deprecate APIs internally first, before deprecating them for clients (to allow validation).
- Add deprecation warnings in the current major version and change the behaviour in the following major release.
- Consider using codemod scripts for changes that require a lot of repetitive manual work.
- Value interoperability.
- Enable gradual adoption by allowing existing functionality to be wrapped by new functionality.
- Perform the minimum amount of work before returning to React.
- Allows React to schedule and split work.
- Be renderer-agnostic
- Don’t assume the app will only run in a browser.
- e.g. https://reactnative.dev
- Aim for elegant APIs but prefer ugly APIs if they avoid work for the client.
- Correct, performant and a good developer experience are more important than elegant.
- Prefer boring code to clever code.
- Avoid new internal abstractions.
- Verbose code is easier to move around and change.
- Use verbose name for APIs.
- Make points of interaction highly visible and distinct.
- Optimize for search (makes automated updates easier).
- Eat Your Own Dog Food
- But be open to the idea that external clients may have other use cases.
There are many patterns that are considered important for React; certainly too many to list here.
A good sources of information about React Patterns is:
Additional information can be found here:
Some examples of common patterns can be found here:
Taken from https://medium.com/@konstankino/2019-reactjs-best-practices-design-patterns-516e1c3ca06a
- When using ReduxJS, split your Reducer code into smaller methods to avoid huge JSON within your Reducer.
- Consider using TypeScript in your apps if you do not do it already.
- Use the create-react-app generator to bootstrap your React app.
- Keep your code DRY. Don’t Repeat Yourself, but keep in mind code duplicate is NOT always a bad thing.
- Avoid having large classes, methods or components, including Reducers.
- Use more robust managers to manage application state, such as Redux.
- Use event synchronizer, such as Redux-Thunk, for interactions with your back end API.
- Avoid passing too many attributes or arguments. Limit yourself to five props that you pass into your component.
- Use React defaultProps and React propTypes.
- Use linter, break up lines that are too long.
- Keep your own jslint configuration file.
- Always use a dependency manager with a lock file, such as NPM or yarn.
- Test your commonly accessed code, code that is complex and prone to bugs.
- Write more tests that give more test coverage for your code with a little effort and test code to ensure its proper functioning.
- Every time you find a bug, make sure you write a test first.
- Use function-based components by starting to use React Hooks, a new React way to create state-full components.
- Use ES6 de-structuring for your props.
- Use conditional rendering.
- User
map()
to collect and render collections of components. - Use partial components, such as
<>
…</>
- Name your event handlers with handle prefixes, such as
handleClick()
orhandleUpdate()
. - Use
onChange
to control your inputs, such asonChange={this.handleInputChange}
. - Use JEST to test your React code.