From b177ff64889f520e2e423e4152ccc9900d72927c Mon Sep 17 00:00:00 2001 From: Lee Robinson Date: Mon, 15 Jan 2024 21:19:59 -0600 Subject: [PATCH] examples: Update redis example with `useOptimistic` (#60596) --- examples/with-redis/app/form.tsx | 47 +++++++++++++++++++------------- examples/with-redis/app/page.tsx | 41 ++++++++++++++++------------ examples/with-redis/package.json | 20 +++++++------- 3 files changed, 61 insertions(+), 47 deletions(-) diff --git a/examples/with-redis/app/form.tsx b/examples/with-redis/app/form.tsx index 45a13efb00011..d69650a43ef04 100644 --- a/examples/with-redis/app/form.tsx +++ b/examples/with-redis/app/form.tsx @@ -1,7 +1,7 @@ "use client"; import clsx from "clsx"; -import { useOptimistic, useRef } from "react"; +import { useOptimistic, useRef, useTransition } from "react"; import { saveFeature, upvote } from "./actions"; import { v4 as uuidv4 } from "uuid"; import { Feature } from "./types"; @@ -23,22 +23,26 @@ function Item({ pending: boolean; mutate: any; }) { - const upvoteWithId = upvote.bind(null, feature); + let upvoteWithId = upvote.bind(null, feature); + // eslint-disable-next-line @typescript-eslint/no-unused-vars + let [isPending, startTransition] = useTransition(); return (
{ + onSubmit={(event) => { event.preventDefault(); - mutate({ - updatedFeature: { - ...feature, - score: Number(feature.score) + 1, - }, - pending: true, - }); - await upvote(feature); + startTransition(async () => { + mutate({ + updatedFeature: { + ...feature, + score: Number(feature.score) + 1, + }, + pending: true, + }); + await upvote(feature); + }); }} className={clsx( "p-6 mx-8 flex items-center border-t border-l border-r", @@ -73,8 +77,8 @@ type FeatureState = { }; export default function FeatureForm({ features }: { features: Feature[] }) { - const formRef = useRef(null); - const [state, mutate] = useOptimistic( + let formRef = useRef(null); + let [state, mutate] = useOptimistic( { features, pending: false }, function createReducer(state, newState: FeatureState) { if (newState.newFeature) { @@ -112,6 +116,8 @@ export default function FeatureForm({ features }: { features: Feature[] }) { score: "1", }; let saveWithNewFeature = saveFeature.bind(null, featureStub); + // eslint-disable-next-line @typescript-eslint/no-unused-vars + let [isPending, startTransition] = useTransition(); return ( <> @@ -120,7 +126,7 @@ export default function FeatureForm({ features }: { features: Feature[] }) { className="relative my-8" ref={formRef} action={saveWithNewFeature} - onSubmit={async (event) => { + onSubmit={(event) => { event.preventDefault(); let formData = new FormData(event.currentTarget); let newFeature = { @@ -128,12 +134,15 @@ export default function FeatureForm({ features }: { features: Feature[] }) { title: formData.get("feature") as string, }; - mutate({ - newFeature, - pending: true, - }); formRef.current?.reset(); - await saveFeature(newFeature, formData); + startTransition(async () => { + mutate({ + newFeature, + pending: true, + }); + + await saveFeature(newFeature, formData); + }); }} > ) { } async function getFeatures() { - let itemIds = await kv.zrange("items_by_score", 0, 100, { - rev: true, - }); + try { + let itemIds = await kv.zrange("items_by_score", 0, 100, { + rev: true, + }); - if (!itemIds.length) { - return []; - } + if (!itemIds.length) { + return []; + } - let multi = kv.multi(); - itemIds.forEach((id) => { - multi.hgetall(`item:${id}`); - }); + let multi = kv.multi(); + itemIds.forEach((id) => { + multi.hgetall(`item:${id}`); + }); - let items: Feature[] = await multi.exec(); - return items.map((item) => { - return { - ...item, - score: item.score, - created_at: item.created_at, - }; - }); + let items: Feature[] = await multi.exec(); + return items.map((item) => { + return { + ...item, + score: item.score, + created_at: item.created_at, + }; + }); + } catch (error) { + console.error(error); + return []; + } } export default async function Page() { diff --git a/examples/with-redis/package.json b/examples/with-redis/package.json index fd4572bb9e6a6..09e8a4236c02e 100644 --- a/examples/with-redis/package.json +++ b/examples/with-redis/package.json @@ -6,20 +6,20 @@ "start": "next start" }, "dependencies": { - "@types/node": "20.10.3", - "@types/react": "18.2.42", - "@types/react-dom": "18.2.17", + "@types/node": "20.11.0", + "@types/react": "18.2.47", + "@types/react-dom": "18.2.18", "@types/uuid": "9.0.7", - "@vercel/kv": "^1.0.0", + "@vercel/kv": "^1.0.1", "autoprefixer": "10.4.16", - "clsx": "^2.0.0", - "geist": "^1.2.0", - "next": "canary", - "postcss": "^8.4.32", + "clsx": "^2.1.0", + "geist": "^1.2.1", + "next": "latest", + "postcss": "^8.4.33", "react": "18.2.0", "react-dom": "18.2.0", - "tailwindcss": "3.3.6", - "typescript": "5.3.2", + "tailwindcss": "3.4.1", + "typescript": "5.3.3", "uuid": "^9.0.1" } }