使用Liveblocks创建房间时遭遇TypeError错误求助
TypeError: (0 , liveblocks_react__WEBPACK_IMPORTED_MODULE_1_.default) 不是一个函数 错误详情
服务器错误
TypeError: (0 , liveblocks_react__WEBPACK_IMPORTED_MODULE_1_.default) 不是一个函数
该错误在页面生成时发生,控制台日志将显示在终端窗口。
来源
liveblocks.config.ts (85:78) @ client83 | useRemoveReaction,
84 | }
85 | } = createRoomContext<Presence, Storage, UserMeta, RoomEvent, ThreadMetadata>(client, {
| ^
86 | async resolveUsers({ userIds }) {
87 | // 仅用于评论功能。返回从userIds获取的用户信息列表,该信息用于评论、提及等场景。
88 | // 从userIds获取用户信息
相关代码
room.tsx
import {ReactNode} from 'react'; import {ClientSideSuspense} from '@liveblocks/react' import {RoomProvider} from '@/liveblocks.config'; interface RoomProps { children: ReactNode roomId: string; fallback: NonNullable<ReactNode> | null; }; const Room = ({ children, roomId, fallback, }: RoomProps) => { return ( <RoomProvider id={roomId} initialPresence={ {} } // initialStorage={{ // layers: new LiveMap<string, LiveObject<Layer>>(), // layerIds: new LiveList(), // }} > <ClientSideSuspense fallback={fallback}> {() => children} </ClientSideSuspense> </RoomProvider> ) } export default Room
page.tsx
import React from 'react' import Canvas from './_components/canvas' import Room from '@/components/room'; import SimpleLoader from '@/components/Loaders/simple-loader'; interface BoardIdPageProps { params: { boardId: string; }; }; const BoardIdPage = ({ params, }: BoardIdPageProps) => { return ( <main className="h-full w-full relative bg-neutral-100 touch-none" > <Room roomId={params.boardId} fallback={<SimpleLoader />}> <Canvas boardId={params.boardId} /> </Room> </main> ) } export default BoardIdPage
liveblocks.config.ts
import { createClient } from "@liveblocks/client"; import { createRoomContext } from "@liveblocks/react"; const client = createClient({ publicApiKey: "pk_dev_Mlm5l54BhELjDRrhRrvlbBAih9GS5wCPSTLaXLeBXZpiDI7Cw_BCNyURhNuTEtvt", }); // Presence代表房间内每个用户都存在且会自动同步的属性,可通过`user.presence`访问,必须可JSON序列化。 type Presence = { // cursor: { x: number, y: number } | null, // ... }; // 可选:Storage代表房间内持久化的共享文档,即使所有用户离开也会保留。Storage下的字段通常是LiveList、LiveMap、LiveObject实例,其更新会自动持久化并同步到所有连接的客户端。 type Storage = { // author: LiveObject<{ firstName: string, lastName: string }>, // ... }; // 可选:UserMeta代表每个用户的静态/只读元数据,由自定义认证后端提供(若使用),适用于会话期间不会更改的数据,如用户名或头像。 type UserMeta = { // id?: string, // 可通过`user.id`访问 // info?: Json, // 可通过`user.info`访问 }; // 可选:本房间内广播和监听的自定义事件类型,使用联合类型表示多个事件,必须可JSON序列化。 type RoomEvent = { // type: "NOTIFICATION", // ... }; // 可选:使用评论功能时,ThreadMetadata代表每个线程的元数据,仅可包含布尔值、字符串和数字。 export type ThreadMetadata = { // resolved: boolean; // quote: string; // time: number; }; export const { suspense: { RoomProvider, useRoom, useMyPresence, useUpdateMyPresence, useSelf, useOthers, useOthersMapped, useOthersConnectionIds, useOther, useBroadcastEvent, useEventListener, useErrorListener, useStorage, useObject, useMap, useList, useBatch, useHistory, useUndo, useRedo, useCanUndo, useCanRedo, useMutation, useStatus, useLostConnectionListener, useThreads, useUser, useCreateThread, useEditThreadMetadata, useCreateComment, useEditComment, useDeleteComment, useAddReaction, useRemoveReaction, } } = createRoomContext<Presence, Storage, UserMeta, RoomEvent, ThreadMetadata>(client, { async resolveUsers({ userIds }) { // 仅用于评论功能。返回从`userIds`获取的用户信息列表,该信息用于评论、提及等场景。 // const usersData = await __fetchUsersFromDB__(userIds); // // return usersData.map((userData) => ({ // name: userData.name, // avatar: userData.avatar.src, // })); return []; }, async resolveMentionSuggestions({ text, roomId }) { // 仅用于评论功能。返回匹配`text`的用户ID列表,这些ID用于在编辑器中输入时创建提及列表。 // // 例如当输入"@jo"时,`text`为"jo",应返回John和Joanna的用户ID数组: // ["john@example.com", "joanna@example.com"] // const userIds = await __fetchAllUserIdsFromDB__(roomId); // // 若没有`text`则返回所有用户ID // if (!text) { // return userIds; // } // // 否则根据搜索文本过滤用户ID并返回 // return userIds.filter((userId) => // userId.toLowerCase().includes(text.toLowerCase()) // ); return []; }, });
这个错误的核心是Liveblocks版本不兼容或API导入/调用方式错误,以下是具体修复步骤:
统一依赖版本
确保@liveblocks/client和@liveblocks/react版本完全一致,版本不匹配会导致API冲突。执行命令更新到最新版:npm install @liveblocks/client@latest @liveblocks/react@latest # 或使用yarn yarn add @liveblocks/client@latest @liveblocks/react@latest修正
createRoomContext的导入与调用
如果你使用的是Liveblocks v1.x及以上版本,Suspense模式的API已调整,需要从专门的路径导入:// 替换原导入语句 import { createRoomContext } from "@liveblocks/react/suspense";同时,返回的
RoomProvider及hooks无需从suspense属性中解构,直接获取即可:export const { RoomProvider, useRoom, useMyPresence, // ... 其他需要的hooks } = createRoomContext<Presence, Storage, UserMeta, RoomEvent, ThreadMetadata>(client, { // 配置项保持不变 });验证RoomProvider使用
确保room.tsx中导入的RoomProvider来自修正后的liveblocks.config.ts,且id属性正确传入roomId,这部分你的代码已符合要求,无需额外修改。
内容的提问来源于stack exchange,提问作者Oculus

