From 11c8bd52ad811ca8170eadcdd61b12c1d516e53e Mon Sep 17 00:00:00 2001 From: Kathryn Middleton Date: Tue, 5 Dec 2023 16:31:36 +0000 Subject: [PATCH 1/3] add usage example --- src/content/reference/react/useOptimistic.md | 62 ++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/content/reference/react/useOptimistic.md b/src/content/reference/react/useOptimistic.md index 2095a4198f7..4475c4c721b 100644 --- a/src/content/reference/react/useOptimistic.md +++ b/src/content/reference/react/useOptimistic.md @@ -143,3 +143,65 @@ export async function deliverMessage(message) { ``` + +--- + +### Optimistically update the UI while waiting for a network request {/*optimistically-update-while-waiting-for-network*/} + + + +```js like-button.js active +import { useOptimistic } from "react"; + +export function LikeButton({ likes, updateLikes, disabled }) { + const [optimisticLikes, addOptimisticLike] = useOptimistic( + likes, + (likes) => likes + 1 + ); + + async function addLike() { + addOptimisticLike(); + await updateLikes(likes); + } + + return ( + + ); +} +``` + + +```js App.js +import { useState } from "react"; +import { LikeButton } from "./like-button.js"; + +export default function App() { + const [likes, setLikes] = useState(0); + const [updating, setUpdating] = useState(false); + async function updateLikes(num) { + setUpdating(true); + await new Promise((res) => setTimeout(res, 1000)); + setLikes(num + 1); + setUpdating(false); + } + return ( + + ); +} +``` + +```json package.json hidden +{ + "dependencies": { + "react": "experimental", + "react-dom": "experimental", + "react-scripts": "^5.0.0" + }, + "main": "/index.js", + "devDependencies": {} +} +``` + + \ No newline at end of file From 719d70528b827b71a3616ad352c39ab305d5508e Mon Sep 17 00:00:00 2001 From: Kathryn Middleton Date: Tue, 5 Dec 2023 17:03:00 +0000 Subject: [PATCH 2/3] add startTransition --- src/content/reference/react/useOptimistic.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/content/reference/react/useOptimistic.md b/src/content/reference/react/useOptimistic.md index 4475c4c721b..210a367e882 100644 --- a/src/content/reference/react/useOptimistic.md +++ b/src/content/reference/react/useOptimistic.md @@ -151,7 +151,7 @@ export async function deliverMessage(message) { ```js like-button.js active -import { useOptimistic } from "react"; +import { startTransition, useOptimistic } from "react"; export function LikeButton({ likes, updateLikes, disabled }) { const [optimisticLikes, addOptimisticLike] = useOptimistic( @@ -160,8 +160,10 @@ export function LikeButton({ likes, updateLikes, disabled }) { ); async function addLike() { - addOptimisticLike(); - await updateLikes(likes); + startTransition(() => { + addOptimisticLike(); + updateLikes(likes); + }) } return ( From 34521a75adc75f3cc2b2284e5ceb64fc6507f84d Mon Sep 17 00:00:00 2001 From: Kathryn Middleton Date: Tue, 5 Dec 2023 18:31:21 +0000 Subject: [PATCH 3/3] Add caveat section --- src/content/reference/react/useOptimistic.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/content/reference/react/useOptimistic.md b/src/content/reference/react/useOptimistic.md index 210a367e882..179b4c43df3 100644 --- a/src/content/reference/react/useOptimistic.md +++ b/src/content/reference/react/useOptimistic.md @@ -59,6 +59,11 @@ function AppContainer() { * `optimisticState`: The resulting optimistic state. It is equal to `state` unless an action is pending, in which case it is equal to the value returned by `updateFn`. * `addOptimistic`: `addOptimistic` is the dispatching function to call when you have an optimistic update. It takes one argument, `optimisticValue`, of any type and will call the `updateFn` with `state` and `optimisticValue`. + +#### Caveats {/*caveats*/} + +* An optimistic state update needs to be called in an action or wrapped with `startTransition`. If it's used outside an action or a transition React will throw an error. + --- ## Usage {/*usage*/}