Favorite Toggle Button with useOptimistic

lada496

Yuko

Posted on September 2, 2024

Favorite Toggle Button with useOptimistic

This is an idea of implementing a toggle button with useOptimistic. useOptimistic is a React experimental hook that allows apps to update UI optimistically while the actual state updates with async operation. You can learn more about it with those links.
useOptimistic - React
Data Fetching: Server Actions and Mutations | Next.js

Here is the main code of my component.

    import { useOptimistic, useRef } from 'react'
    import { Button } from './ui/button'
    import { HeartIcon, HeartFilledIcon } from '@radix-ui/react-icons'

    export function FavoriteButton({
      isFavorite,
      placeId,
    }: {
      isFavorite: boolean
      placeId: string
    }) {

      async function formAction(formData: FormData) {
        addOptimisticFavorite(!isFavorite)
        formRef.current?.reset()
        const placeId = formData.get('placeId')
        await fetch(`/api/favorite`, {
          method: 'POST',
          body: JSON.stringify({ placeId }),
        })
      }

      const [optimisticIsFavorite, addOptimisticFavorite] = useOptimistic(
        isFavorite,
        (state) => !state,
      )
      return (
        <form action={formAction} ref={formRef}>
          <input type="hidden" value={placeId} name="placeId" />
          <Button variant="ghost" type="submit" onClick={handleClick}>
            {optimisticIsFavorite ? <HeartFilledIcon /> : <HeartIcon />}
          </Button>
        </form>
      )
    }
Enter fullscreen mode Exit fullscreen mode

optimisticFavorite toggles immediately after users click the button and gets rolled back when the component receives isFavorite whose value is different from optimisticFavorite. Otherwise, optimisticFavorite keeps the client-side state.

In my real code, unfortunately, I needed to deal with two different cases to update isFavorite in my app, which is not ideal, and the code gets a little messy. Please visit the link below if you’re interested.
ai-gourmet-navigator/src/components/favorite-button.tsx at main ·…

That’s it! Thank you for reading :)

💖 💪 🙅 🚩
lada496
Yuko

Posted on September 2, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related