skip to Main Content

I have a delete user button on my user page (route: /users/) who call the delete user api’s route.
Then after this call, i execute a router.psuh('/users') to go back to my users list
But my /users page is like cached and the data is not re fetched.

This is my delete user button :

"use client"

import deleteUser from "@/lib/users/deleteUser"
import { revalidatePath } from "next/cache"
import { useRouter } from 'next/navigation'

type Props = {
  user: User
}

export default function DeleteUserButton({ user }: Props) {
  const router = useRouter()

  const deleteUserCallback = async (id: string) => {
    deleteUser(id)
    .then(() => {
      router.push("/users")
    })
  }

  return (
    <button type="button" onClick={() => deleteUserCallback(user.id)}>
      Delete
    </button>
  )
}

My user page :

import getUserByUsername from "@/lib/users/getUserByUsername"
import DeleteUserButton from "./components/DeleteUserButton"

type Props = {
  params: {
    username: string
  }
}

export async function generateMetadata({ params: { username } }: Props) {
  const user = await getUserByUsername(username)

  if (user === null) {
    return {
      title: "User not found",
    }
  }

  return {
    title: `${user.lastName} ${user.firstName}`,
  }
}

export default async function UserPage({ params: { username } }: Props) {
  const user = await getUserByUsername(username)

  if (user === null) {
    return <div>User not found</div>
  }

  return (
    <div>
      <p>User: {user.email}</p>
      <DeleteUserButton user={user} />
    </div>
  )
}

And then my users page :

import getUsers from "@/lib/users/getUsers"
import Link from "next/link"

export default async function UsersPage() {
  const usersReq = await getUsers()
  const users = usersReq.users

  return (
    <div>
      {users.map((user) => {
        return (
          <p key={user.id}>
            <Link href={`/users/${user.username}`}>
              {user.username}
            </Link>
            {user.firstName}
          </p>
        )
      })}
    </div>
  )
}

Idk if i have to change my fetch users list method ?


UPDATE

My getUsers function (i’m using an external API):

export default async function getUsers():
  Promise<{
    users: User[],
    pagination: Pagination
  }>
{
  const res = await fetch(process.env.NEXT_PUBLIC_API_BASE_URL + '/users?pageSize=20', {
    cache: 'no-cache',
  });

  if (!res.ok)
    throw new Error('Error fetching');

  return res.json();
}

If i add a tag with a revalidateTag it looks like this :

(getUsers)

export default async function getUsers():
  Promise<{
    users: User[],
    pagination: Pagination
  }>
{
  const res = await fetch(process.env.NEXT_PUBLIC_API_BASE_URL + '/users?pageSize=20', {
    cache: 'no-cache',
    next: {
      tags: ['users']
    }
  });

  if (!res.ok)
    throw new Error('Error fetching');

  return res.json();
}

And now my DeleteUserButton component :

"use client"

import deleteUser from "@/lib/users/deleteUser"
import { revalidateTag } from "next/cache"
import { useRouter } from 'next/navigation'

type Props = {
  user: User
}

export default function DeleteUserButton({ user }: Props) {
  const router = useRouter()

  const deleteUserCallback = async (id: string) => {
    deleteUser(id)
    .then(() => {
      revalidateTag("users")
      router.push("/users")
    })
  }

  return (
    <button type="button" onClick={() => deleteUserCallback(user.id)}>
      Delete
    </button>
  )
}

But now i get this error when i click on the delete button :
error

2

Answers


  1. Chosen as BEST ANSWER

    I was trying to execute the revalidate directly from a Client Component that is seems to be not possible.

    To execute a revalidatePath / revalidateTag from a Client Component :

    And now it works ! ;)


  2. You need to invalidate the cache when a user is created / updated / deleted, or disable it for getUsers altogether:

    You can read more about this in the official documentation.

    Edit:

    About the error you are getting:

    Error: Invariant: static generation store missing in revalidateTag users
    

    This might be a bug on Vercel’s side, see this GitHub issue.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search