Skip to content

Commit 75b90f9

Browse files
wgao19markerikson
authored andcommitted
Add / change docs about v6 (#1148)
* Add v6 related info to Quick Start * Remove doc regarding directly passing store * Add doc passing `context` to `<Provider />` * Add docs around accessing store with v6 * Rework "Accessing Store" content Reordered sections Added explanation of internals and warning note * Remove context content from "Quick Start" * Copy CSS changes from main Redux site
1 parent 5088345 commit 75b90f9

File tree

6 files changed

+295
-21
lines changed

6 files changed

+295
-21
lines changed

docs/api/Provider.md

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@ The `<Provider />` makes the Redux `store` available to any nested components th
1313

1414
Since any React component in a React Redux app can be connected, most applications will render a `<Provider>` at the top level, with the entire app’s component tree inside of it.
1515

16-
Normally, you can’t use a connected component unless it is nested inside of a `<Provider>` .
17-
18-
Note: If you really need to, you can manually pass `store` as a prop to a connected component, but we only recommend to do this for stubbing `store` in unit tests, or in non-fully-React codebases. Normally, you should just use `<Provider>`.
16+
Normally, you can’t use a connected component unless it is nested inside of a `<Provider>`.
1917

2018
### Props
2119

@@ -25,6 +23,29 @@ The single Redux `store` in your application.
2523
`children` (ReactElement)
2624
The root of your component hierarchy.
2725

26+
`context`
27+
You may provide a context instance. If you do so, you will need to provide the same context instance to all of your connected components as well. Failure to provide the correct context results in runtime error:
28+
29+
> Invariant Violation
30+
>
31+
> Could not find "store" in the context of "Connect(MyComponent)". Either wrap the root component in a <Provider>, or pass a custom React context provider to <Provider> and the corresponding React context consumer to Connect(Todo) in connect options.
32+
33+
**Note:** You do not need to provide custom context in order to access the store.
34+
React Redux exports the context instance it uses by default so that you can access the store by:
35+
36+
```js
37+
import { ReactReduxContext } from 'react-redux'
38+
39+
// in your connected component
40+
render() {
41+
return (
42+
<ReactReduxContext.Consumer>
43+
{({ store }) => <div>{store}</div>}
44+
</ReactReduxContext.Consumer>
45+
)
46+
}
47+
```
48+
2849
### Example Usage
2950

3051
In the example below, the `<App />` component is our root-level component. This means it’s at the very top of our component hierarchy.

docs/introduction/quick-start.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ yarn add react-redux
2727

2828
You'll also need to [install Redux](https://redux-docs.netlify.com/introduction/installation) and [set up a Redux store](https://redux-docs.netlify.com/recipes/configuring-your-store) in your app.
2929

30-
## `Provider` and `connect`
30+
## `<Provider />`
3131

3232
React Redux provides `<Provider />`, which makes the Redux store available to the rest of your app:
3333

@@ -49,6 +49,8 @@ ReactDOM.render(
4949
)
5050
```
5151

52+
## `connect()`
53+
5254
React Redux provides a `connect` function for you to connect your component to the store.
5355

5456
Normally, you’ll call `connect` in this way:
@@ -73,6 +75,7 @@ export default connect(
7375
)(Counter)
7476
```
7577

78+
7679
## Help and Discussion
7780

7881
The **[#redux channel](https://discord.gg/0ZcbPKXt5bZ6au5t)** of the **[Reactiflux Discord community](http://www.reactiflux.com)** is our official resource for all questions related to learning and using Redux. Reactiflux is a great place to hang out, ask questions, and learn - come join us!
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
---
2+
id: accessing-store
3+
title: Accessing the Store
4+
hide_title: true
5+
sidebar_label: Accessing the Store
6+
---
7+
8+
# Accessing the Store
9+
10+
React Redux provides APIs that allow your components to dispatch actions and subscribe to data updates from the store.
11+
12+
As part of that, React Redux abstracts away the details of which store you are using, and the exact details of how that
13+
store interaction is handled. In typical usage, your own components should never need to care about those details, and
14+
won't ever reference the store directly. React Redux also internally handles the details of how the store and state are
15+
propagated to connected components, so that this works as expected by default.
16+
17+
However, there may be certain use cases where you may need to customize how the store and state are propagated to
18+
connected components, or access the store directly. Here are some examples of how to do this.
19+
20+
## Understanding Context Usage
21+
22+
Internally, React Redux uses [React's "context" feature](https://reactjs.org/docs/context.html) to make the
23+
Redux store accessible to deeply nested connected components. As of React Redux version 6, this is normally handled
24+
by a single default context object instance generated by `React.createContext()`, called `ReactReduxContext`.
25+
26+
React Redux's `<Provider>` component uses `<ReactReduxContext.Provider>` to put the Redux store and the current store
27+
state into context, and `connect` uses `<ReactReduxContext.Consumer>` to read those values and handle updates.
28+
29+
## Providing Custom Context
30+
31+
Instead of using the default context instance from React Redux, you may supply your own custom context instance.
32+
33+
```js
34+
<Provider context={MyContext} store={store}>
35+
<App />
36+
</Provider>
37+
```
38+
39+
If you supply a custom context, React Redux will use that context instance instead of the one it creates and exports by default.
40+
41+
After you’ve supplied the custom context to `<Provider />`, you will need to supply this context instance to all of your connected components that are expected to connect to the same store:
42+
43+
```js
44+
// You can pass the context as an option to connect
45+
export default connect(
46+
mapState,
47+
mapDispatch,
48+
null,
49+
{ context: MyContext }
50+
)(MyComponent)
51+
52+
// or, call connect as normal to start
53+
const ConnectedComponent = connect(
54+
mapState,
55+
mapDispatch
56+
)(MyComponent)
57+
58+
// Later, pass the custom context as a prop to the connected component
59+
<ConnectedComponent context={MyContext} />
60+
```
61+
62+
The following runtime error occurs when React Redux does not find a store in the context it is looking. For example:
63+
64+
- You provided a custom context instance to `<Provider />`, but did not provide the same instance (or did not provide any) to your connected components.
65+
- You provided a custom context to your connected component, but did not provide the same instance (or did not provide any) to `<Provider />`.
66+
67+
> Invariant Violation
68+
>
69+
> Could not find "store" in the context of "Connect(MyComponent)". Either wrap the root component in a `<Provider>`, or pass a custom React context provider to `<Provider>` and the corresponding React context consumer to Connect(Todo) in connect options.
70+
71+
## Multiple Stores
72+
73+
[Redux was designed to use a single store](https://redux.js.org/api/store#a-note-for-flux-users).
74+
However, if you are in an unavoidable position of needing to use multiple stores, with v6 you may do so by providing (multiple) custom contexts.
75+
This also provides a natural isolation of the stores as they live in separate context instances.
76+
77+
```js
78+
// a naive example
79+
const ContextA = React.createContext();
80+
const ContextB = React.createContext();
81+
82+
// assuming reducerA and reducerB are proper reducer functions
83+
const storeA = createStore(reducerA);
84+
const storeB = createStore(reducerB);
85+
86+
// supply the context instances to Provider
87+
function App() {
88+
return (
89+
<Provider store={storeA} context={ContextA} />
90+
<Provider store={storeB} context={ContextB}>
91+
<App />
92+
</Provider>
93+
</Provider>
94+
);
95+
}
96+
97+
// fetch the corresponding store with connected components
98+
// you need to use the correct context
99+
connect(mapStateA, null, null, { context: ContextA })(MyComponentA)
100+
101+
// You may also pass the alternate context instance directly to the connected component instead
102+
<ConnectedMyComponentA context={ContextA} />
103+
104+
// it is possible to chain connect()
105+
// in this case MyComponent will receive merged props from both stores
106+
compose(
107+
connect(mapStateA, null, null, { context: ContextA }),
108+
connect(mapStateB, null, null, { context: ContextB })
109+
)(MyComponent);
110+
```
111+
112+
## Using `ReactReduxContext` Directly
113+
114+
In rare cases, you may need to access the Redux store directly in your own components. This can be done by rendering
115+
the appropriate context consumer yourself, and accessing the `store` field out of the context value.
116+
117+
> **Note**: This is **_not_ considered part of the React Redux public API, and may break without notice**. We do recognize
118+
> that the community has use cases where this is necessary, and will try to make it possible for users to build additional
119+
> functionality on top of React Redux, but our specific use of context is considered an implementation detail.
120+
> If you have additional use cases that are not sufficiently covered by the current APIs, please file an issue to discuss
121+
> possible API improvements.
122+
123+
```js
124+
import { ReactReduxContext } from 'react-redux'
125+
126+
// in your connected component
127+
function MyConnectedComponent() {
128+
return (
129+
<ReactReduxContext.Consumer>
130+
{({ store }) => {
131+
// do something useful with the store, like passing it to a child
132+
// component where it can be used in lifecycle methods
133+
}}
134+
</ReactReduxContext.Consumer>
135+
)
136+
}
137+
```
138+
139+
## Further Resources
140+
141+
- CodeSandbox example: [A reading list app with theme using a separate store](https://codesandbox.io/s/92pm9n2kl4), implemented by providing (multiple) custom context(s).
142+
- Related issues:
143+
- [#1132: Update docs for using a different store key](https://github.com/reduxjs/react-redux/issues/1132)
144+
- [#1126: `<Provider>` misses state changes that occur between when its constructor runs and when it mounts](https://github.com/reduxjs/react-redux/issues/1126)

website/sidebars.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
],
88
"Using React Redux": [
99
"using-react-redux/connect-mapstate",
10-
"using-react-redux/connect-mapdispatch"
10+
"using-react-redux/connect-mapdispatch",
11+
"using-react-redux/accessing-store"
1112
],
1213
"API Reference": [
1314
"api/connect",

website/siteConfig.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,13 @@ const siteConfig = {
4444
/* Colors for website */
4545
colors: {
4646
primaryColor: "#764ABC",
47-
secondaryColor: "#764ABC",
47+
secondaryColor: "#40216F",
48+
accentColor1: "#717171",
49+
accentColor2: "#F3EAFF",
50+
accentColor3: "#D2B9F3",
51+
accentColor4: "#ECF4F9",
52+
accentColor5: "#CBDDEA",
53+
accentColor6: "#2F5773"
4854
},
4955

5056
/* Custom fonts for website */

0 commit comments

Comments
 (0)