├── .gitignore
├── package.json
├── render-props
└── README.md
├── flexible-compound-components
└── README.md
├── provider-pattern
└── README.md
├── state-reducers
└── README.md
├── prop-collection
└── README.md
├── prop-getters
└── README.md
├── hoc
└── README.md
├── compound-components
└── README.md
├── hooks
└── README.md
├── .all-contributorsrc
├── README.md
├── react-best-practices
└── README.md
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-advanced-patterns",
3 | "version": "1.0.0",
4 | "description": "Repo containing some advanced patterns for react and for writing better React applications",
5 | "main": "index.js",
6 | "repository": "https://github.com/manjula91/react-advanced-patterns.git",
7 | "author": "Manjula Dube",
8 | "license": "MIT",
9 | "devDependencies": {
10 | "all-contributors-cli": "^5.4.1"
11 | },
12 | "scripts": {
13 | "contributors:add": "all-contributors add",
14 | "contributors:generate": "all-contributors generate"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/render-props/README.md:
--------------------------------------------------------------------------------
1 | # Render props
2 |
3 | ### What are render props
4 |
5 | Render props are simply props that accept a function.
6 |
7 | ### What is so special about this pattern
8 |
9 | Render props separate logic from the UI. The component that implements the logic doesn't decide how the UI is rendered, which is why I like this pattern a lot. The other reason is how easy it is to make the entire component declarative by just rendering what you need.
10 |
11 | We can easily extend the API of our component and access only the logic required for rendering the UI. This makes render props more flexible as compared to Higher Order Components.
12 |
13 | Also almost all patterns implemented using HOC's can be easily converted to the Render Prop pattern.
14 |
15 | ### Example
16 |
17 | This is a simple example of how the imperative fetch API can be converted into a declarative one (inspired by Apollo's Query component).
18 |
19 | [Fetch using render props](https://codesandbox.io/s/9yzwmkj7kp)
20 |
--------------------------------------------------------------------------------
/flexible-compound-components/README.md:
--------------------------------------------------------------------------------
1 | # Flexible Compound Components
2 |
3 | What are Flexible Compound Components?
4 |
5 | * This is better version of compound components which makes use of context API and compound component together. This will work even if your order of component changes (which is quite often). This will basically allow user to have more flexibility by using React context to share the implicit state to our child components. We will start with defining childContextTypes, providing the value with getChildContext, and, on each of the components that need that context, we define contextTypes so that React will pass the context that is being asked for. This is more flexible than just using compound components. The consumer component are basically designed in a way that they use render prop in order to work.
6 |
7 | ### Example
8 |
9 | This is an example of grouping the RadioButton highly inspired by [semantic-ui-react](https://react.semantic-ui.com/collections/form/).
10 |
11 | [Grouping the radio buttons](https://codesandbox.io/s/z304lk196l)
12 |
13 |
--------------------------------------------------------------------------------
/provider-pattern/README.md:
--------------------------------------------------------------------------------
1 | # Provider Pattern
2 |
3 | ### What is the Provider Pattern
4 |
5 | Provider pattern is pattern where we can share data between multiple components. The main Component is responsible for data and state changes (Provider) and the child components receive the data via a special component (Consumer).
6 |
7 | ### What is so special about this pattern
8 |
9 | The best way to create this pattern is using React's new Context API. A method `createContext` is exposed by React from which you can create a Provider and a Consumer.
10 |
11 | The problem is that when we want to pass data to components nested deep, we need to pass the props to each and every nested component, which becomes hard to refactor. The term coined for this is called **prop-drilling** (most probably by [Kent C. Dodds](https://twitter.com/kentcdodds)).
12 |
13 | The Provider pattern solves this problem. In whichever component you want to access the data, just wrap it by the `Consumer` component which exposes all the state and methods via a render prop (yay!). This ensures that data stays where it is really required.
14 |
15 | ### Example
16 |
17 | This example shows a simple form component made using React's Context API.
18 |
19 | [Provider Pattern](https://codesandbox.io/s/p524z98zvx)
20 |
--------------------------------------------------------------------------------
/state-reducers/README.md:
--------------------------------------------------------------------------------
1 | # State Reducer
2 |
3 | ### What is a State Reducer
4 |
5 | State Reducer is a pattern where you can set the state of the component in a way similar to the reducer function in Redux.
6 |
7 | ### What is so special about this pattern
8 |
9 | State Reducer pattern is pretty similar to the Redux reducer. It takes the previous state along with the current changes to be made in the state and merges them.
10 |
11 | The main advantage of this pattern is that we can use the same components we have, without modifying the existing API and add a new way of updating state whilst keeping the UI separate from the logic (because of the widely loved render-props pattern). The reducer method which we write can be re-used in other components as we do not need to manage the state in our component.
12 |
13 | This pattern stands out when all you want is to extend you API for state changes and keeping the current functionality untouched.
14 |
15 | ### Example
16 |
17 | This is an example of how a simple Form component can provide a different API altogether for creating a form.
18 |
19 | [Forms with State Reducers](https://codesandbox.io/s/9802yr86q4)
20 |
21 | Here is another example showing the use of multiple reducers for the state reduer pattern.
22 |
23 | [Multiple State Reducers](https://codesandbox.io/s/1o8o2xzm37)
24 |
--------------------------------------------------------------------------------
/prop-collection/README.md:
--------------------------------------------------------------------------------
1 | # Prop Collections
2 |
3 | ### What are prop collection?
4 |
5 | Prop Collection is a pattern where we can access props from the parent component by passing a single object of props.
6 |
7 | ### What is so special about this pattern?
8 |
9 | This pattern allows us to spread the entire props required on the required component that is passed from the parent.
10 | This ensures that the component receives all the props and we can also add our own props or override the current props.
11 |
12 | ```jsx
13 | getInputProps = {
14 | type: "text",
15 | onChange: this.onChange
16 | };
17 |
18 |
19 |
20 | ```
21 |
22 | I would prefer using Prop Getters to be more flexible since Prop Collection passes object instead of function which is not very flexible. Also there is a disadvantage for prop collection pattern: as we would need to pass the value externally. There is no way we can send it via props. So for eg you would also have to pass the event handler explicitly. Also if you want to add your own event handler along with the one provided by the parent, you need to extract the method from the parent and combine with your own handler which becomes rather messy.
23 |
24 | ### Example
25 |
26 | Here's the codesanbox [example](https://codesandbox.io/s/yrjmqol7j) for prop collection
27 |
--------------------------------------------------------------------------------
/prop-getters/README.md:
--------------------------------------------------------------------------------
1 | # Prop Getters
2 |
3 | ### What are prop getters
4 |
5 | Prop getters is a very unique pattern. This pattern involves the usage of spreading a function call in which we add our custom props and these are merged with the default props provided by the component.
6 |
7 | ### What is so special about this pattern ?
8 |
9 | Prop getters is a flexible pattern to provide props to the required component. This pattern is great when we want to add our own props without overriding the ones give by the main component.
10 |
11 | Suppose we have an input and we spread the props we obtained from the parent component like this:
12 |
13 | ```jsx
14 |
15 | ```
16 |
17 | Now these props we obtained include an onChange method for the input. What if we want to implement our own onChange method?
18 | There is a way but it is messy
19 |
20 | ```jsx
21 | const {onChange, ...rest} = inputProps
22 | {
25 | onChange()
26 | myOnChangeMethod()
27 | }}
28 | />
29 | ```
30 |
31 | A better solution is to provide our method using prop-getters
32 |
33 | ```jsx
34 |
39 | ```
40 |
41 | Now it's upto the main parent component to provide a mechanism to call both the internal and supplied method.
42 | Easy!!!
43 |
44 | ### Example
45 |
46 | Below is an example shows how a Form component can manage state using prop-getters
47 |
48 | [Prop Getters in action](https://codesandbox.io/s/2pq87v9r4r)
49 |
--------------------------------------------------------------------------------
/hoc/README.md:
--------------------------------------------------------------------------------
1 | # Higher Order Components
2 |
3 | ### What are Higher Order Components
4 |
5 | Higher order components are a pattern in which a function accepts a component and returns an enhanced version of the component by injecting the required props.
6 |
7 | ### What is so special about this pattern
8 |
9 | HOC's are a pattern used a lot. The most common being the `connect` method of `react-redux` or `withRouter` of `react-router-dom`. This pattern wraps the given Component and returns the same component just by adding extra props to it. This type of function should be pure as it cannot modify the original component, just enhance it.
10 |
11 | The drawback to HOC's is prop-collision. A component wrapped with two or more higher order methods could have props of the same name and any one of those could be overriden. This is where render-props comes to the rescue.
12 |
13 | For prop-collision, lets take the same example as the one in the example section. What if instead of one set of data, I have to render two sets of data, which means I need two fetch hoc's.
14 |
15 | The code will be something like this -
16 |
17 | ```jsx
18 | let App = fetchHOC({ url: 'my-url-1' })(App)
19 | App = fetchHOC({ url: 'my-url-2' })(App)
20 | ```
21 |
22 | The data prop being the same will cause just one set of data to be displayed, which is incorrect. Now take a look at the render-prop example and see for yourself that this case can be easily handled.
23 |
24 | ### Example
25 |
26 | This example demonstrates how we can use the Fetch API as a higher order component.
27 |
28 | [Fetch using HOC](https://codesandbox.io/s/734060mlm6)
29 |
--------------------------------------------------------------------------------
/compound-components/README.md:
--------------------------------------------------------------------------------
1 | # Compound Components
2 |
3 | ### What are Compound Components?
4 |
5 | Compound Component is a pattern in React where a component doesn't work by itself and needs other specific components to be its children or parents in order to operate. But they still have the control to do lot of stuff on them :)
6 | It is a pattern in which components are used together such that they share an implicit state that let’s them communicate with each other in the background.
7 |
8 | > Think of compound components like the ```