chore: use dynamic import to avoid page hydrated

This commit is contained in:
Steven
2023-03-22 23:42:59 +08:00
parent ecf981b361
commit fcd5d544ba
5 changed files with 28 additions and 22 deletions

View File

@ -1,7 +1,7 @@
import { useEffect, useRef, useState } from "react"; import { useEffect, useRef, useState } from "react";
import { toast } from "react-hot-toast"; import { toast } from "react-hot-toast";
import TextareaAutosize from "react-textarea-autosize"; import TextareaAutosize from "react-textarea-autosize";
import { localUser, useChatStore, useMessageStore } from "@/store"; import { useChatStore, useMessageStore, useUserStore } from "@/store";
import { CreatorRole } from "@/types"; import { CreatorRole } from "@/types";
import { generateUUID } from "@/utils"; import { generateUUID } from "@/utils";
import Icon from "../Icon"; import Icon from "../Icon";
@ -13,6 +13,7 @@ interface Props {
const MessageTextarea = (props: Props) => { const MessageTextarea = (props: Props) => {
const { disabled, sendMessage } = props; const { disabled, sendMessage } = props;
const userStore = useUserStore();
const chatStore = useChatStore(); const chatStore = useChatStore();
const messageStore = useMessageStore(); const messageStore = useMessageStore();
const [value, setValue] = useState<string>(""); const [value, setValue] = useState<string>("");
@ -45,7 +46,7 @@ const MessageTextarea = (props: Props) => {
messageStore.addMessage({ messageStore.addMessage({
id: generateUUID(), id: generateUUID(),
chatId: chatStore.currentChat.id, chatId: chatStore.currentChat.id,
creatorId: localUser.id, creatorId: userStore.currentUser.id,
creatorRole: CreatorRole.User, creatorRole: CreatorRole.User,
createdAt: Date.now(), createdAt: Date.now(),
content: value, content: value,

View File

@ -1,5 +1,5 @@
import { marked } from "marked"; import { marked } from "marked";
import { localUser } from "@/store"; import { useUserStore } from "@/store";
import { Message } from "@/types"; import { Message } from "@/types";
interface Props { interface Props {
@ -8,7 +8,8 @@ interface Props {
const MessageView = (props: Props) => { const MessageView = (props: Props) => {
const message = props.message; const message = props.message;
const isCurrentUser = message.creatorId === localUser.id; const userStore = useUserStore();
const isCurrentUser = message.creatorId === userStore.currentUser.id;
return ( return (
<div className={`w-full flex flex-row justify-start items-start my-4 ${isCurrentUser ? "justify-end pl-8 sm:pl-24" : "pr-8 sm:pr-24"}`}> <div className={`w-full flex flex-row justify-start items-start my-4 ${isCurrentUser ? "justify-end pl-8 sm:pl-24" : "pr-8 sm:pr-24"}`}>

View File

@ -1,7 +1,7 @@
import axios from "axios"; import axios from "axios";
import { useEffect, useRef, useState } from "react"; import { useEffect, useRef, useState } from "react";
import { defaultChat, getAssistantById, getPromptOfAssistant, localUser, useChatStore, useMessageStore } from "@/store"; import { getAssistantById, getPromptOfAssistant, useChatStore, useMessageStore } from "@/store";
import { Chat, CreatorRole, Message } from "@/types"; import { CreatorRole } from "@/types";
import { generateUUID } from "@/utils"; import { generateUUID } from "@/utils";
import Icon from "../Icon"; import Icon from "../Icon";
import Header from "./Header"; import Header from "./Header";
@ -11,21 +11,10 @@ import MessageTextarea from "./MessageTextarea";
const ChatView = () => { const ChatView = () => {
const chatStore = useChatStore(); const chatStore = useChatStore();
const messageStore = useMessageStore(); const messageStore = useMessageStore();
const [messageList, setMessageList] = useState<Message[]>([]);
const [currentChat, setCurrentChat] = useState<Chat | null>(null);
const [isRequesting, setIsRequesting] = useState<boolean>(false); const [isRequesting, setIsRequesting] = useState<boolean>(false);
const chatViewRef = useRef<HTMLDivElement>(null); const chatViewRef = useRef<HTMLDivElement>(null);
const currentChat = chatStore.currentChat;
useEffect(() => { const messageList = messageStore.messageList.filter((message) => message.chatId === currentChat?.id);
if (!getAssistantById(chatStore.currentChat.assistantId)) {
chatStore.setCurrentChat(defaultChat);
}
setCurrentChat(chatStore.currentChat);
}, [chatStore]);
useEffect(() => {
setMessageList(messageStore.messageList.filter((message) => message.chatId === currentChat?.id));
}, [currentChat?.id, messageStore.messageList]);
useEffect(() => { useEffect(() => {
setTimeout(() => { setTimeout(() => {
@ -54,7 +43,7 @@ const ChatView = () => {
content: prompt, content: prompt,
}, },
...messageList.map((message) => ({ ...messageList.map((message) => ({
role: message.creatorId === localUser.id ? CreatorRole.User : CreatorRole.Assistant, role: message.creatorRole,
content: message.content, content: message.content,
})), })),
], ],

View File

@ -1,7 +1,13 @@
import { NextPage } from "next"; import { NextPage } from "next";
import Head from "next/head"; import Head from "next/head";
import React from "react"; import React from "react";
import ChatView from "@/components/ChatView"; import dynamic from "next/dynamic";
// Use dynamic import to avoid page hydrated.
// reference: https://github.com/pmndrs/zustand/issues/1145#issuecomment-1316431268
const ChatView = dynamic(() => import("@/components/ChatView"), {
ssr: false,
});
const ChatPage: NextPage = () => { const ChatPage: NextPage = () => {
return ( return (

View File

@ -1,8 +1,17 @@
import { User } from "@/types"; import { User } from "@/types";
import { create } from "zustand";
export const localUser: User = { const localUser: User = {
id: "local-user", id: "local-user",
name: "Local user", name: "Local user",
description: "", description: "",
avatar: "", avatar: "",
}; };
interface UserState {
currentUser: User;
}
export const useUserStore = create<UserState>()(() => ({
currentUser: localUser,
}));