Skip to content

Commit 885c1cc

Browse files
committed
Update docs for v8 final
- Removed `connectAdvanced` and `pure` descriptions - Updated all `render()` examples to show `createRoot` - Added note that `batch` isn't needed with React 18 - Added TS props for `Provider` and documented `serverState` - Updated TS usage descriptions - Added warnings about `@types/react@18`
1 parent 1da5216 commit 885c1cc

File tree

12 files changed

+147
-190
lines changed

12 files changed

+147
-190
lines changed

README.md

+10-14
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,25 @@ Performant and flexible.
55

66
![GitHub Workflow Status](https://img.shields.io/github/workflow/status/reduxjs/react-redux/Tests?style=flat-square) [![npm version](https://img.shields.io/npm/v/react-redux.svg?style=flat-square)](https://www.npmjs.com/package/react-redux)
77
[![npm downloads](https://img.shields.io/npm/dm/react-redux.svg?style=flat-square)](https://www.npmjs.com/package/react-redux)
8-
[![redux channel on discord](https://img.shields.io/badge/[email protected]?style=flat-square)](http://www.reactiflux.com)
8+
[![#redux channel on Discord](https://img.shields.io/badge/[email protected]?style=flat-square)](http://www.reactiflux.com)
99

1010
## Installation
1111

1212
### Using Create React App
1313

14-
The recommended way to start new apps with React Redux is by using the [official Redux+JS template](https://github.com/reduxjs/cra-template-redux) for [Create React App](https://github.com/facebook/create-react-app), which takes advantage of [Redux Toolkit](https://redux-toolkit.js.org/).
14+
The recommended way to start new apps with React Redux is by using the [official Redux+JS/TS templates](https://github.com/reduxjs/cra-template-redux) for [Create React App](https://github.com/facebook/create-react-app), which takes advantage of [Redux Toolkit](https://redux-toolkit.js.org/).
1515

1616
```sh
17+
# JS
1718
npx create-react-app my-app --template redux
19+
20+
# TS
21+
npx create-react-app my-app --template redux-typescript
1822
```
1923

2024
### An Existing React App
2125

22-
React Redux 7.1 requires **React 16.8.3 or later.**
26+
React Redux 8.0 requires **React 16.8.3 or later** (or React Native 0.59 or later).
2327

2428
To use React Redux with your React app, install it as a dependency:
2529

@@ -40,24 +44,16 @@ modules](https://webpack.js.org/api/module-methods/#commonjs).
4044

4145
If you don’t yet use [npm](http://npmjs.com/) or a modern module bundler, and would rather prefer a single-file [UMD](https://github.com/umdjs/umd) build that makes `ReactRedux` available as a global object, you can grab a pre-built version from [cdnjs](https://cdnjs.com/libraries/react-redux). We _don’t_ recommend this approach for any serious application, as most of the libraries complementary to Redux are only available on [npm](http://npmjs.com/).
4246

43-
## React Native
44-
45-
As of React Native 0.18, React Redux 5.x should work with React Native. If you have any issues with React Redux 5.x on React Native, run `npm ls react` and make sure you don’t have a duplicate React installation in your `node_modules`. We recommend that you use `[email protected]` which is better at avoiding these kinds of issues.
46-
4747
## Documentation
4848

49-
The React Redux docs are now published at **https://react-redux.js.org** .
50-
51-
We're currently expanding and rewriting our docs content - check back soon for more updates!
49+
The React Redux docs are published at **https://react-redux.js.org** .
5250

5351
## How Does It Work?
5452

55-
We do a deep dive on how React Redux works in [this readthesource episode](https://www.youtube.com/watch?v=VJ38wSFbM3A).
56-
57-
Also, the post [The History and Implementation of React-Redux](https://blog.isquaredsoftware.com/2018/11/react-redux-history-implementation/)
53+
The post [The History and Implementation of React-Redux](https://blog.isquaredsoftware.com/2018/11/react-redux-history-implementation/)
5854
explains what it does, how it works, and how the API and implementation have evolved over time.
5955

60-
Enjoy!
56+
There's also a [Deep Dive into React-Redux](https://blog.isquaredsoftware.com/2019/06/presentation-react-redux-deep-dive/) talk that covers some of the same material at a higher level.
6157

6258
## License
6359

docs/api/Provider.md

+66-10
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,51 @@ The [Hooks](./hooks.md) and [`connect`](./connect.md) APIs can then access the p
2020

2121
### Props
2222

23-
`store` ([Redux Store](https://redux.js.org/api/store))
24-
The single Redux `store` in your application.
23+
```ts
24+
interface ProviderProps<A extends Action = AnyAction, S = any> {
25+
/**
26+
* The single Redux store in your application.
27+
*/
28+
store: Store<S, A>
29+
30+
/**
31+
* An optional server state snapshot. Will be used during initial hydration render
32+
* if available, to ensure that the UI output is consistent with the HTML generated on the server.
33+
* New in 8.0
34+
*/
35+
serverState?: S
36+
37+
/**
38+
* Optional context to be used internally in react-redux. Use React.createContext()
39+
* to create a context to be used.
40+
* If this is used, you'll need to customize `connect` by supplying the same
41+
* context provided to the Provider.
42+
* Initial value doesn't matter, as it is overwritten with the internal state of Provider.
43+
*/
44+
context?: Context<ReactReduxContextValue<S, A>>
45+
46+
/** The top-level React elements in your component tree, such as `<App />` **/
47+
children: ReactNode
48+
}
49+
```
2550

26-
`children` (ReactElement)
27-
The root of your component hierarchy.
51+
Typically, you only need to pass `<Provider store={store}>`.
2852

29-
`context`
30-
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:
53+
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 this runtime error:
3154

3255
> Invariant Violation
3356
>
3457
> 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.
3558
36-
### Example Usage
59+
## React 18 SSR Usage
60+
61+
As of React-Redux v8, `<Provider>` now accepts a `serverState` prop for use in SSR hydration scenarios. This is necessary if you are calling `hydrateRoot` in order to avoid hydration mismatches.
62+
63+
You should pass the entire serialized state from the server as the `serverState` prop, and React will use this state for the initial hydration render. After that, it will apply any updates from changes that occurred on the client during the setup process.
64+
65+
## Examples
66+
67+
### Basic Usage
3768

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

@@ -47,10 +78,35 @@ import createStore from './createReduxStore'
4778

4879
const store = createStore()
4980

50-
ReactDOM.render(
81+
// As of React 18
82+
const root = ReactDOM.createRoot(document.getElementById('root'))
83+
root.render(
5184
<Provider store={store}>
5285
<App />
53-
</Provider>,
54-
document.getElementById('root')
86+
</Provider>
87+
)
88+
```
89+
90+
### React 18 SSR Hydration
91+
92+
In this example, the client has received HTML rendered by the server, as well as a serialized Redux state attached to `window`. The serialized state is used to both pre-fill the store's contents, _and_ passed as the `serverState` prop to `<Provider>`
93+
94+
```tsx title="src/index.ts"
95+
import { hydrateRoot } from 'react-dom/client'
96+
import { configureStore } from '@reduxjs/toolkit'
97+
import { Provider } from 'react-redux'
98+
99+
const preloadedState = window.__PRELOADED_STATE__
100+
101+
const clientStore = configureStore({
102+
reducer: rootReducer,
103+
preloadedState,
104+
})
105+
106+
hydrateRoot(
107+
document.getElementById('root'),
108+
<Provider store={clientStore} serverState={preloadedState}>
109+
<App />
110+
</Provider>
55111
)
56112
```

docs/api/batch.md

+9-2
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,22 @@ description: 'API > batch: batching React rendering updates'
1111
# `batch()`
1212

1313
```js
14-
batch((fn: Function))
14+
batch((fn: () => void))
1515
```
1616

1717
_added in v7.0.0_
1818

19+
:::info
20+
21+
**If you're using React 18, you do not need to use the `batch` API**. React 18 automatically batches _all_ state updates, no matter where they're queued.
22+
23+
:::
24+
1925
React's `unstable_batchedUpdates()` API allows any React updates in an event loop tick to be batched together into a single render pass. React already uses this internally for its own event handler callbacks. This API is actually part of the renderer packages like ReactDOM and React Native, not the React core itself.
2026

2127
Since React-Redux needs to work in both ReactDOM and React Native environments, we've taken care of importing this API from the correct renderer at build time for our own use. We also now re-export this function publicly ourselves, renamed to `batch()`. You can use it to ensure that multiple actions dispatched outside of React only result in a single render update, like this:
2228

23-
```js
29+
```ts
2430
import { batch } from 'react-redux'
2531

2632
function myThunk() {
@@ -37,3 +43,4 @@ function myThunk() {
3743
## References
3844

3945
- [`unstable_batchedUpdates()` API from React](https://github.com/facebook/react/commit/b41883fc708cd24d77dcaa767cde814b50b457fe)
46+
- [React 18 Working Group: Automatic Batching for Fewer Renders in React 18](https://github.com/reactwg/react-18/discussions/21)

docs/api/connect-advanced.md

-93
This file was deleted.

docs/api/connect.md

+10-25
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ description: 'API > connect: a Higher-Order Component to interact with Redux'
1010

1111
# `connect()`
1212

13+
:::tip
14+
15+
`connect` still works and is supported in React-Redux 8.x. However, [**we recommend using the hooks API as the default**](./hooks.md).
16+
17+
:::
18+
1319
## Overview
1420

1521
The `connect()` function connects a React component to a Redux store.
@@ -202,7 +208,6 @@ The return value of `mergeProps` is referred to as `mergedProps` and the fields
202208
```js
203209
{
204210
context?: Object,
205-
pure?: boolean,
206211
areStatesEqual?: Function,
207212
areOwnPropsEqual?: Function,
208213
areStatePropsEqual?: Function,
@@ -226,23 +231,11 @@ connect(mapStateToProps, mapDispatchToProps, null, { context: MyContext })(
226231
)
227232
```
228233
229-
#### `pure: boolean`
230-
231-
- default value: `true`
232-
233-
Assumes that the wrapped component is a “pure” component and does not rely on any input or state other than its props and the selected Redux store’s state.
234-
235-
When `options.pure` is true, `connect` performs several equality checks that are used to avoid unnecessary calls to `mapStateToProps`, `mapDispatchToProps`, `mergeProps`, and ultimately to `render`. These include `areStatesEqual`, `areOwnPropsEqual`, `areStatePropsEqual`, and `areMergedPropsEqual`. While the defaults are probably appropriate 99% of the time, you may wish to override them with custom implementations for performance or other reasons.
236-
237-
We provide a few examples in the following sections.
238-
239234
#### `areStatesEqual: (next: Object, prev: Object) => boolean`
240235
241236
- default value: `strictEqual: (next, prev) => prev === next`
242237
243-
When pure, compares incoming store state to its previous value.
244-
245-
_Example 1_
238+
Compares incoming store state to its previous value.
246239
247240
```js
248241
const areStatesEqual = (next, prev) =>
@@ -251,22 +244,14 @@ const areStatesEqual = (next, prev) =>
251244
252245
You may wish to override `areStatesEqual` if your `mapStateToProps` function is computationally expensive and is also only concerned with a small slice of your state. The example above will effectively ignore state changes for everything but that slice of state.
253246
254-
_Example 2_
255-
256-
If you have impure reducers that mutate your store state, you may wish to override `areStatesEqual` to always return false:
257-
258-
```js
259-
const areStatesEqual = () => false
260-
```
261-
262247
This would likely impact the other equality checks as well, depending on your `mapStateToProps` function.
263248
264249
#### `areOwnPropsEqual: (next: Object, prev: Object) => boolean`
265250
266251
- default value: `shallowEqual: (objA, objB) => boolean`
267252
( returns `true` when each field of the objects is equal )
268253
269-
When pure, compares incoming props to its previous value.
254+
Compares incoming props to its previous value.
270255
271256
You may wish to override `areOwnPropsEqual` as a way to whitelist incoming props. You'd also have to implement `mapStateToProps`, `mapDispatchToProps` and `mergeProps` to also whitelist props. (It may be simpler to achieve this other ways, for example by using [recompose's mapProps](https://github.com/acdlite/recompose/blob/master/docs/API.md#mapprops).)
272257
@@ -275,13 +260,13 @@ You may wish to override `areOwnPropsEqual` as a way to whitelist incoming props
275260
- type: `function`
276261
- default value: `shallowEqual`
277262

278-
When pure, compares the result of `mapStateToProps` to its previous value.
263+
Compares the result of `mapStateToProps` to its previous value.
279264

280265
#### `areMergedPropsEqual: (next: Object, prev: Object) => boolean`
281266

282267
- default value: `shallowEqual`
283268

284-
When pure, compares the result of `mergeProps` to its previous value.
269+
Compares the result of `mergeProps` to its previous value.
285270

286271
You may wish to override `areStatePropsEqual` to use `strictEqual` if your `mapStateToProps` uses a memoized selector that will only return a new object if a relevant prop has changed. This would be a very slight performance improvement, since would avoid extra equality checks on individual props each time `mapStateToProps` is called.
287272

0 commit comments

Comments
 (0)