为什么 UI 在 router.refresh() 之后有时没有更新,但它确实更新到后端?

Why UI didn't update sometimes after router.refresh() but it did update to the backend?

提问人:susanliu 提问时间:11/14/2023 更新时间:11/14/2023 访问量:12

问:

我正在实现一个固定消息方法,就像信使一样。下面是它的样子:enter image description here

在我更改固定消息后,它应该立即更新顶部的固定消息。但是,有时我必须单击刷新按钮才能更新。下面是它的样子:I changed the pinned message the left window

这是我的代码(在message.tsx中):

"use client";
import { useState } from "react";
import useMessage from "@/hooks/useMessages";
import { Dialog,DialogContent,DialogFooter } from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import {useDocument} from "@/hooks/useDocument";
type MessageProps = {
  id:number;
  isSender:boolean;
  text:string;
  state:string;
};
export default function({ id,isSender,text ,state}: MessageProps) {
  const [open,setOpen] = useState(false);
  const {postMessage,updateMessage,retriveMessage}=useMessage();
  const {pinnedMessageId,setpinnedMessageId}=useDocument();

  const handlePinMessage = async() => {
    setpinnedMessageId(text);//TODO sometimes can't rerender immediately
    setOpen(false);
  }
  return(
    <div id={id.toString()}>
      {pinnedMessageId!==""&&pinnedMessageId===text?
        <div className="fixed top-10 left-[40%] h-10 w-[50%]">
          <div className="flex items-stretch place-content-center content-center">
            <div className="pt-1 text-2xl self-center">
              {pinnedMessageId}
            </div>
          </div>
        </div>
        :<></>
      }
      {/*other html element*/}
    </div>
  );
}

这是我的 setpinnedMessageId 的样子:

import { useEffect, useMemo, useState } from "react";

import { useSession } from "next-auth/react";
import { useParams, useRouter } from "next/navigation";

import { useDebounce } from "use-debounce";

import { pusherClient } from "@/lib/pusher/client";
import type { Document, User ,Message} from "@/lib/types/db";

type PusherPayload = {
  senderId: User["id"];
  document: Document;
};

export const useDocument = () => {
  const { docId } = useParams();
  const documentId = Array.isArray(docId) ? docId[0] : docId;

  const [document, setDocument] = useState<Document | null>(null);
  const [dbDocument, setDbDocument] = useState<Document | null>(null);
  const [debouncedDocument] = useDebounce(document, 300);
  const router = useRouter();

  const { data: session } = useSession();
  const userId = session?.user?.id;

  const isSynced = useMemo(() => {
    if (document === null || dbDocument === null) return true;
    return (
      document.pinnedMessageId === dbDocument.pinnedMessageId
    );
  }, [document, dbDocument]);

  // When the debounced document changes, update the document
  useEffect(() => {
    if (debouncedDocument === null) return;
    if (isSynced) return;

    const updateDocument = async () => {
      if (!debouncedDocument) return;
      const res = await fetch(`/api/documents/${documentId}`, {
        method: "PUT",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          pinnedMessageId: debouncedDocument.pinnedMessageId,
        }),
      });
      if (!res.ok) {
        return;
      }
      const data: Document = await res.json();
      // Update the navbar if the title changed
      if (dbDocument?.pinnedMessageId!== data.pinnedMessageId) {
        router.refresh();
        console.log("refreshed_id");
      }
      setDbDocument(data);
    };
    updateDocument();
    console.log("updated");
  }, [debouncedDocument, documentId, router, dbDocument, isSynced]);

  // Subscribe to pusher events
  useEffect(() => {
    if (!documentId) return;
    // Private channels are in the format: private-...
    const channelName = `private-${documentId}`;
    try {
      const channel = pusherClient.subscribe(channelName);
      channel.bind("doc:update", ({ senderId, document }: PusherPayload) => {
        if (senderId === userId) {
          return;
        }
        setDocument(document);
        setDbDocument(document);
        router.refresh();
        console.log("refreshshshshshshsh");
        const messageContainer = window.document.getElementById("messages container");
        if (messageContainer) {
          messageContainer.scrollTop = messageContainer.scrollHeight-messageContainer.clientHeight+10;
        }
      });
    } catch (error) {
      console.error(error);
      router.push("/docs");
    }

    // Unsubscribe from pusher events when the component unmounts
    return () => {
      pusherClient.unsubscribe(channelName);
    };
  }, [documentId, router, userId]);

  useEffect(() => {
    if (!documentId) return;
    const fetchDocument = async () => {
      const res = await fetch(`/api/documents/${documentId}`);
      if (!res.ok) {
        setDocument(null);
        router.push("/docs");
        return;
      }
      const data = await res.json();
      setDocument(data);
      setDbDocument(data);
    };
    fetchDocument();
  }, [documentId, router]);

  const pinnedMessageId = document?.pinnedMessageId || "";
  const setpinnedMessageId = (newPinnedMessageId:string) => {
    if (document === null) return;
    setDocument({
     ...document,
      pinnedMessageId:newPinnedMessageId,
      // latestUpdatedAt:new Date(),
    });
  }
  return {
    documentId,
    document,
    pinnedMessageId,
    setpinnedMessageId,
  };
};

我删除了一些我认为不相关的内容。

当我更改固定消息时,它确实如此,所以这意味着路由器确实刷新了,并且推送器工作正常。所以我不知道为什么我的固定消息没有更新。有人可以告诉我为什么会发生这种情况以及如何解决它吗?console.log("refreshed_id")

打字稿 react-hooks 路由器 rerender next-router

评论


答: 暂无答案