Skip to content

Commit

Permalink
Merge branch 'main' into release-3.8
Browse files Browse the repository at this point in the history
  • Loading branch information
alessbell authored Jul 25, 2023
2 parents 0f1cde3 + 5000438 commit 506a14c
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 7 deletions.
6 changes: 3 additions & 3 deletions ROADMAP.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# 🔮 Apollo Client Roadmap

**Last updated: 2023-06-20**
**Last updated: 2023-07-18**

For up to date release notes, refer to the project's [Changelog](https://github.com/apollographql/apollo-client/blob/main/CHANGELOG.md).

Expand All @@ -15,7 +15,7 @@ For up to date release notes, refer to the project's [Changelog](https://github.

## [3.8.0](https://github.com/apollographql/apollo-client/milestone/30)

_Approximate Date: GA TBD after user feedback_
_Approximate Date: August 7th, 2023_

Currently in active development and in the beta stage. React 18 users will get a lot out of this release since it introduces support for Suspense. There are also new features added to the core as well. Here's a brief overview:

Expand All @@ -28,7 +28,7 @@ Currently in active development and in the beta stage. React 18 users will get
- New client-side `@nonreactive` directive
- A new optional `removeTypenameFromVariables` Apollo Link that will automatically strip `__typename` from your variables for each request

Try it today: `npm i @apollo/client@beta` and let us know what you think!
Try it today: `npm i @apollo/client@rc` and let us know what you think!

## [3.9.0](https://github.com/apollographql/apollo-client/milestone/32)

Expand Down
57 changes: 57 additions & 0 deletions docs/source/api/react/hooks.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,63 @@ function DontReadTheComments({ repoFullName }) {

> Refer to the [Subscriptions](../../data/subscriptions/) section for a more in-depth overview of `useSubscription`.
#### Subscriptions and React 18 Automatic Batching

With React 18's [automatic batching](https://react.dev/blog/2022/03/29/react-v18#new-feature-automatic-batching), multiple state updates may be grouped into a single re-render for better performance.

If your subscription API sends multiple messages at the same time or in very fast succession (within fractions of a millisecond), it is likely that only the last message received in that narrow time frame will result in a re-render.

Consider the following component:

```jsx
export function Subscriptions() {
const { data, error, loading } = useSubscription(query);
const [accumulatedData, setAccumulatedData] = useState([]);

useEffect(() => {
setAccumulatedData((prev) => [...prev, data]);
}, [data]);

return (
<>
{loading && <p>Loading...</p>}
{JSON.stringify(accumulatedData, undefined, 2)}
</>
);
}
```

If your subscription back-end emits two messages with the same timestamp, only the last message received by Apollo Client will be rendered. This is because React 18 will batch these two state updates into a single re-render.

Since the component above is using `useEffect` to push `data` into a piece of local state on each `Subscriptions` re-render, the first message will never be added to the `accumulatedData` array since its render was skipped.

Instead of using `useEffect` here, we can re-write this component to use the `onData` callback function accepted in `useSubscription`'s `options` object:

```jsx
export function Subscriptions() {
const [accumulatedData, setAccumulatedData] = useState([]);
const { data, error, loading } = useSubscription(
query,
{
onData({ data }) {
setAccumulatedData((prev) => [...prev, data])
}
}
);

return (
<>
{loading && <p>Loading...</p>}
{JSON.stringify(accumulatedData, undefined, 2)}
</>
);
}
```

> ⚠️ **Note:** The `useSubscription` option `onData` is available in Apollo Client >= 3.7. In previous versions, the equivalent option is named `onSubscriptionData`.
Now, the first message will be added to the `accumulatedData` array since `onData` is called _before_ the component re-renders. React 18 automatic batching is still in effect and results in a single re-render, but with `onData` we can guarantee each message received after the component mounts is added to `accumulatedData`.

### Function Signature

```ts
Expand Down
6 changes: 3 additions & 3 deletions docs/source/api/react/ssr.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ import { getDataFromTree } from "@apollo/client/react/ssr";

### Result

`getDataFromTree` returns a promise (`Promise<string>`) which resolves when the data is ready in your Apollo Client store. The result is generated using [`ReactDOMServer.renderToStaticMarkup`](https://reactjs.org/docs/react-dom-server.html#rendertostaticmarkup) under the hood.
`getDataFromTree` returns a promise (`Promise<string>`) which resolves when the data is ready in your Apollo Client store. The result is generated using [`ReactDOMServer.renderToStaticMarkup`](https://react.dev/reference/react-dom/server/renderToStaticMarkup) under the hood.

### Example

See [Executing queries with `getDataFromTree`](../../performance/server-side-rendering/#executing-queries-with-getdatafromtree).

## `renderToStringWithData`

The `renderToStringWithData` function is similar to `getDataFromTree`, but uses [`ReactDOMServer.renderToString`](https://reactjs.org/docs/react-dom-server.html#rendertostring) to render its result instead of [`ReactDOMServer.renderToStaticMarkup`](https://reactjs.org/docs/react-dom-server.html#rendertostaticmarkup) (the React docs help explain the difference).
The `renderToStringWithData` function is similar to `getDataFromTree`, but uses [`ReactDOMServer.renderToString`](https://react.dev/reference/react-dom/server/renderToString) to render its result instead of [`ReactDOMServer.renderToStaticMarkup`](https://react.dev/reference/react-dom/server/renderToStaticMarkup) (the React docs help explain the difference).

```js
import { renderToStringWithData } from "@apollo/client/react/ssr";
Expand All @@ -46,4 +46,4 @@ import { renderToStringWithData } from "@apollo/client/react/ssr";

### Result

`renderToStringWithData` returns a promise (`Promise<string>`) which resolves when the data is ready in your Apollo Client store. The result is generated using [`ReactDOMServer.renderToString`](https://reactjs.org/docs/react-dom-server.html#rendertostring) under the hood.
`renderToStringWithData` returns a promise (`Promise<string>`) which resolves when the data is ready in your Apollo Client store. The result is generated using [`ReactDOMServer.renderToString`](https://react.dev/reference/react-dom/server/renderToString) under the hood.
2 changes: 1 addition & 1 deletion docs/source/performance/server-side-rendering.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ This function walks down the entire tree and executes every required query it en

When the `Promise` resolves, you're ready to render your React tree and return it, along with the current state of the Apollo Client cache.

> Note that if you are rendering your React tree directly to a string (instead of the component-based example below), you will need to use [`renderToStringWithData`](../api/react/ssr/#rendertostringwithdata) instead of `getDataFromTree`. This will ensure the client-side React hydration works correctly by using [`ReactDOMServer.renderToString`](https://reactjs.org/docs/react-dom-server.html#rendertostring) to generate the string.
> Note that if you are rendering your React tree directly to a string (instead of the component-based example below), you will need to use [`renderToStringWithData`](../api/react/ssr/#rendertostringwithdata) instead of `getDataFromTree`. This will ensure the client-side React hydration works correctly by using [`ReactDOMServer.renderToString`](https://react.dev/reference/react-dom/server/renderToString) to generate the string.
The following code replaces the `TODO` comment within the `app.use` call in the example above:

Expand Down
1 change: 1 addition & 0 deletions renovate.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"extends": ["apollo-open-source"],
"ignorePaths": ["**/integration-tests/**"],
"dependencyDashboard": true,
"pathRules": [
{
"paths": ["docs/package.json"],
Expand Down

0 comments on commit 506a14c

Please sign in to comment.