You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js中router.refresh()无法触发页面刷新问题求助

Next.js KanbanAddSheet组件添加任务后页面无法刷新问题

我在KanbanAddSheet组件中实现了onSubmit函数,预期每次添加任务后触发页面刷新,但调用router.refresh()后页面并未刷新。控制台无报错,成功提示toast正常弹出,尝试使用router.push(router.asPath)强制刷新也无效。

组件代码

"use client"

import { zodResolver } from "@hookform/resolvers/zod"
import { useRouter } from "next/navigation"
import React, { useRef, ReactNode } from "react"
import { useForm } from "react-hook-form"
import { upsertKanbanTaskSchema } from "../schema"
import { upsertKanbanTask } from "./actions"
import { toast } from "@/components/ui/use-toast"
import { Sheet, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger } from "@/components/ui/sheet"
import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form"
import { Input } from "@/components/ui/input"
import { Button } from "@/components/ui/button"
import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue } from "@/components/ui/select"
import { z } from "zod"
import { Task } from "../types"

type KanbanUpsertSheetProps = {
  children?: React.ReactNode
  defaultValue?: Task
}

export function KanbanAddSheet({ children }: KanbanUpsertSheetProps) {

  const ref = useRef<HTMLDivElement>(null)
  const router = useRouter()

  const form = useForm({
    resolver: zodResolver(upsertKanbanTaskSchema)
  })
  const onSubmit = form.handleSubmit(async (data) => {
    await upsertKanbanTask(data)
    router.refresh()

    ref.current?.click()
    toast({
      title: 'Sucesso!',
      description: 'Sua tarefa foi adicionada com sucesso.',
    })
  })
  return (
    <Sheet>
      <SheetTrigger asChild>
        <div ref={ref}>{children}</div>
      </SheetTrigger>
      <SheetContent>
        <Form {...form}>
          <form onSubmit={onSubmit} className="space-y-8 h-screen">
            <SheetHeader>
              <SheetTitle>Adicionar Tarefas</SheetTitle>
              <SheetDescription>
                Preencha os campos abaixo para adicionar uma nova tarefa.
              </SheetDescription>
            </SheetHeader>
            <FormField
              control={form.control}
              name="title"
              render={({ field }) => (
                <FormItem>
                  <FormLabel>Título</FormLabel>
                  <FormControl>
                    <Input placeholder="exemplo: Trabalho" {...field} />
                  </FormControl>
                  <FormDescription>
                    Esse é o título da sua tarefa.
                  </FormDescription>
                  <FormMessage />
                </FormItem>
              )}
            />
            <FormField
              control={form.control}
              name="description"
              render={({ field }) => (
                <FormItem>
                  <FormLabel>Descrição</FormLabel>
                  <FormControl>
                    <Input placeholder="exemplo: Enviar Emails para Cliente" {...field} />
                  </FormControl>
                  <FormDescription>
                    Esse é a descrição da sua tarefa.
                  </FormDescription>
                  <FormMessage />
                </FormItem>
              )}
            />
            <FormField
              control={form.control}
              name="status"
              render={({ field }) => (
                <FormItem>
                  <FormLabel>Status</FormLabel>
                  <FormControl>
                    <Select {...field}>
                      <SelectTrigger className="w-full">
                        <SelectValue placeholder="Selecione um Status" />
                      </SelectTrigger>
                      <SelectContent>
                        <SelectGroup>
                          <SelectLabel>Status</SelectLabel>
                          <SelectItem value="a-fazer">A Fazer</SelectItem>
                          <SelectItem value="fazendo">Fazendo</SelectItem>
                          <SelectItem value="feito">Feito</SelectItem>
                        </SelectGroup>
                      </SelectContent>
                    </Select>
                  </FormControl>
                </FormItem>
              )}
            />
            <SheetFooter className="mt-auto">
              <Button type="submit">Adicionar Tarefa</Button>
            </SheetFooter>
          </form>
        </Form>
      </SheetContent>
    </Sheet>
  )
}

尝试的强制刷新代码

const onSubmit = form.handleSubmit(async (data) => {
    await upsertKanbanTask(data)
    
    // force update
    router.push(router.asPath)

    ref.current?.click()
    toast({
        title: 'Sucesso!',
        description: 'Sua tarefa foi adicionada com sucesso.',
    })
})

解决思路

  • 验证数据更新结果:先确认upsertKanbanTask是否真的完成了数据写入。可以在await之后打印返回值,或者直接查看数据库/后端接口的响应结果,排除数据未实际更新的情况。
  • 调整执行顺序:当前代码先调用router.refresh()再关闭Sheet,可能Sheet关闭的操作干扰了路由刷新。可以把ref.current?.click()移到router.refresh()之前,或者使用Sheet组件提供的useSheet hook来获取close函数,更可靠地关闭弹窗。
  • 理解Next.js路由刷新逻辑:router.refresh()只会重新获取服务端渲染的内容,如果你的任务列表是存在客户端状态(比如useState)里的,路由刷新不会更新本地状态。这种情况下,应该在提交成功后手动更新客户端任务列表,而不是依赖路由刷新,这也是更高效的方式。
  • 禁用页面缓存:如果页面开启了缓存,可能导致刷新后内容未更新。可以在页面组件中添加export const dynamic = 'force-dynamic'或者在数据获取函数中设置cache: 'no-store',确保每次请求都获取最新数据。
  • 手动更新状态示例:如果父组件管理任务列表状态,可以传递一个更新函数到KanbanAddSheet组件:
    // 父组件
    const [tasks, setTasks] = useState<Task[]>([])
    
    // 传递给KanbanAddSheet
    <KanbanAddSheet addTask={(newTask) => setTasks([...tasks, newTask])}>
      {/* 触发器内容 */}
    </KanbanAddSheet>
    
    // KanbanAddSheet组件中修改onSubmit
    const onSubmit = form.handleSubmit(async (data) => {
      const newTask = await upsertKanbanTask(data)
      addTask(newTask) // 直接更新本地列表
      ref.current?.click()
      toast({
        title: 'Sucesso!',
        description: 'Sua tarefa foi adicionada com sucesso.',
      })
    })
    

内容的提问来源于stack exchange,提问作者Felipe Kreulich

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 04:00:58