RSC table inside Parallel + Intercepted Route modal does not re-render after Server Action + revalidateTag/revalidatePath on first hard navigation (Next.js 15.4.4) #92125
-
DescriptionWhen using Parallel Routes + Intercepted Routes to render a modal that Environment
Route structureWhat happens
This only happens on the first hard navigation to the app in a Reproduction steps
CodeServer Action: export const server_AsignarRol = async (
usuarioId: string,
sistema: { client_id: string; role_name: string }
): Promise<ServerResult<null>> => {
const result = await fetchServer<null>(`${URL_ASIGNAR_ROL}/${usuarioId}`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(sistema),
});
if (result.ok) revalidateTag(`usuario-detalle-${usuarioId}`);
return result;
};RSC fetch with tag: export const server_ObtenerUsuarioPorId = async (id: string) => {
return fetchServer<UsuarioCompleto>(`${URL_USUARIO_DETALLE}/${id}`, {
method: "GET",
next: { tags: [`usuario-detalle-${id}`] },
});
};RSC table body: export default async function TablaBodySistemasEditar({
idUsuario
}: {
idUsuario: string
}) {
await sleep(1000); // intentional delay for skeleton
const result = await server_ObtenerUsuarioPorId(idUsuario);
const sistemas = (result.data as UsuarioCompleto)?.permisos ?? [];
return (
<tbody>
{sistemas.map((sistema, index) => (
<tr key={index}>
<td>{sistema.client_id}</td>
<td>{sistema.role_name}</td>
</tr>
))}
</tbody>
);
}Table wrapper with Suspense key: export default function TablaSistemasEditar({
idUsuario,
searchParams
}: {
idUsuario: string;
searchParams: { [key: string]: string | string[] | undefined };
}) {
return (
<Suspense
key={JSON.stringify(searchParams)} // key changes to trigger re-render
fallback={<SkeletonTabla columnas={3} filas={3} />}
>
<TablaBodySistemasEditar idUsuario={idUsuario} />
</Suspense>
);
}Client button: const handleAccion = async () => {
await server_AsignarRol(idUsuario, { client_id, role_name });
router.refresh();
};Root cause (hypothesis)On hard navigation (first render, no in-memory router cache), Next.js On soft navigation (subsequent visits, router cache populated), This is consistent with the behavior described in:
Both issues were reportedly closed via PRs #59585 and #63263, but the Expected behaviorAfter a Server Action completes and Current workaroundNone confirmed. Attempted workarounds:
QuestionIs this a known regression in 15.4.x? Is there a supported pattern for |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
|
Have you verified this in latest versions? A lot has changed since 15.4 (15.5 is the latest version on the 15 line) ~ Give the latest 16.2 a try, see if this issue persists there, looks like you don't have to do a full production deploy to verify this, just try it locally. If the issue does persist, I wonder if you could do a quick binary search in the 15.x range. There was a lot of canaries between the latest 14 and 15 - so if something as early as 15.0 still has the issue, then just report back here and I can help further. |
Beta Was this translation helpful? Give feedback.
Have you verified this in latest versions? A lot has changed since 15.4 (15.5 is the latest version on the 15 line) ~ Give the latest 16.2 a try, see if this issue persists there, looks like you don't have to do a full production deploy to verify this, just try it locally.
If the issue does persist, I wonder if you could do a quick binary search in the 15.x range. There was a lot of canaries between the latest 14 and 15 - so if something as early as 15.0 still has the issue, then just report back here and I can help further.