Skip to content

Commit

Permalink
Merge pull request #1902 from reduxjs/docs/v8-docs-updates
Browse files Browse the repository at this point in the history
  • Loading branch information
markerikson committed Apr 16, 2022
2 parents 1da5216 + 885c1cc commit d9464a7
Show file tree
Hide file tree
Showing 12 changed files with 147 additions and 190 deletions.
24 changes: 10 additions & 14 deletions README.md
Expand Up @@ -5,21 +5,25 @@ Performant and flexible.

![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)
[![npm downloads](https://img.shields.io/npm/dm/react-redux.svg?style=flat-square)](https://www.npmjs.com/package/react-redux)
[![redux channel on discord](https://img.shields.io/badge/discord-redux@reactiflux-61DAFB.svg?style=flat-square)](http://www.reactiflux.com)
[![#redux channel on Discord](https://img.shields.io/badge/discord-redux@reactiflux-61DAFB.svg?style=flat-square)](http://www.reactiflux.com)

## Installation

### Using Create React App

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/).
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/).

```sh
# JS
npx create-react-app my-app --template redux

# TS
npx create-react-app my-app --template redux-typescript
```

### An Existing React App

React Redux 7.1 requires **React 16.8.3 or later.**
React Redux 8.0 requires **React 16.8.3 or later** (or React Native 0.59 or later).

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

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

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/).

## React Native

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 `npm@3.x` which is better at avoiding these kinds of issues.

## Documentation

The React Redux docs are now published at **https://react-redux.js.org** .

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

## How Does It Work?

We do a deep dive on how React Redux works in [this readthesource episode](https://www.youtube.com/watch?v=VJ38wSFbM3A).

Also, the post [The History and Implementation of React-Redux](https://blog.isquaredsoftware.com/2018/11/react-redux-history-implementation/)
The post [The History and Implementation of React-Redux](https://blog.isquaredsoftware.com/2018/11/react-redux-history-implementation/)
explains what it does, how it works, and how the API and implementation have evolved over time.

Enjoy!
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.

## License

Expand Down
76 changes: 66 additions & 10 deletions docs/api/Provider.md
Expand Up @@ -20,20 +20,51 @@ The [Hooks](./hooks.md) and [`connect`](./connect.md) APIs can then access the p

### Props

`store` ([Redux Store](https://redux.js.org/api/store))
The single Redux `store` in your application.
```ts
interface ProviderProps<A extends Action = AnyAction, S = any> {
/**
* The single Redux store in your application.
*/
store: Store<S, A>

/**
* An optional server state snapshot. Will be used during initial hydration render
* if available, to ensure that the UI output is consistent with the HTML generated on the server.
* New in 8.0
*/
serverState?: S

/**
* Optional context to be used internally in react-redux. Use React.createContext()
* to create a context to be used.
* If this is used, you'll need to customize `connect` by supplying the same
* context provided to the Provider.
* Initial value doesn't matter, as it is overwritten with the internal state of Provider.
*/
context?: Context<ReactReduxContextValue<S, A>>

/** The top-level React elements in your component tree, such as `<App />` **/
children: ReactNode
}
```

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

`context`
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:
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:

> Invariant Violation
>
> 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.
### Example Usage
## React 18 SSR Usage

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.

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.

## Examples

### Basic Usage

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

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

const store = createStore()

ReactDOM.render(
// As of React 18
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
</Provider>
)
```

### React 18 SSR Hydration

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>`

```tsx title="src/index.ts"
import { hydrateRoot } from 'react-dom/client'
import { configureStore } from '@reduxjs/toolkit'
import { Provider } from 'react-redux'

const preloadedState = window.__PRELOADED_STATE__

const clientStore = configureStore({
reducer: rootReducer,
preloadedState,
})

hydrateRoot(
document.getElementById('root'),
<Provider store={clientStore} serverState={preloadedState}>
<App />
</Provider>
)
```
11 changes: 9 additions & 2 deletions docs/api/batch.md
Expand Up @@ -11,16 +11,22 @@ description: 'API > batch: batching React rendering updates'
# `batch()`

```js
batch((fn: Function))
batch((fn: () => void))
```

_added in v7.0.0_

:::info

**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.

:::

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.

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:

```js
```ts
import { batch } from 'react-redux'

function myThunk() {
Expand All @@ -37,3 +43,4 @@ function myThunk() {
## References

- [`unstable_batchedUpdates()` API from React](https://github.com/facebook/react/commit/b41883fc708cd24d77dcaa767cde814b50b457fe)
- [React 18 Working Group: Automatic Batching for Fewer Renders in React 18](https://github.com/reactwg/react-18/discussions/21)
93 changes: 0 additions & 93 deletions docs/api/connect-advanced.md

This file was deleted.

35 changes: 10 additions & 25 deletions docs/api/connect.md
Expand Up @@ -10,6 +10,12 @@ description: 'API > connect: a Higher-Order Component to interact with Redux'

# `connect()`

:::tip

`connect` still works and is supported in React-Redux 8.x. However, [**we recommend using the hooks API as the default**](./hooks.md).

:::

## Overview

The `connect()` function connects a React component to a Redux store.
Expand Down Expand Up @@ -202,7 +208,6 @@ The return value of `mergeProps` is referred to as `mergedProps` and the fields
```js
{
context?: Object,
pure?: boolean,
areStatesEqual?: Function,
areOwnPropsEqual?: Function,
areStatePropsEqual?: Function,
Expand All @@ -226,23 +231,11 @@ connect(mapStateToProps, mapDispatchToProps, null, { context: MyContext })(
)
```
#### `pure: boolean`
- default value: `true`
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.
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.
We provide a few examples in the following sections.
#### `areStatesEqual: (next: Object, prev: Object) => boolean`
- default value: `strictEqual: (next, prev) => prev === next`
When pure, compares incoming store state to its previous value.
_Example 1_
Compares incoming store state to its previous value.
```js
const areStatesEqual = (next, prev) =>
Expand All @@ -251,22 +244,14 @@ const areStatesEqual = (next, prev) =>
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.
_Example 2_
If you have impure reducers that mutate your store state, you may wish to override `areStatesEqual` to always return false:
```js
const areStatesEqual = () => false
```
This would likely impact the other equality checks as well, depending on your `mapStateToProps` function.
#### `areOwnPropsEqual: (next: Object, prev: Object) => boolean`
- default value: `shallowEqual: (objA, objB) => boolean`
( returns `true` when each field of the objects is equal )
When pure, compares incoming props to its previous value.
Compares incoming props to its previous value.
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).)
Expand All @@ -275,13 +260,13 @@ You may wish to override `areOwnPropsEqual` as a way to whitelist incoming props
- type: `function`
- default value: `shallowEqual`

When pure, compares the result of `mapStateToProps` to its previous value.
Compares the result of `mapStateToProps` to its previous value.

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

- default value: `shallowEqual`

When pure, compares the result of `mergeProps` to its previous value.
Compares the result of `mergeProps` to its previous value.

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.

Expand Down

0 comments on commit d9464a7

Please sign in to comment.