英文:
Component from a third party library not working on server side in NextJS
问题
我遇到了一个让我有点困惑的问题。
我最近开始使用新的 NextJS v13,它使用 React 服务器组件。
我正在一个项目中使用它,该项目依赖于我编写的一个小型私有第三方库,该库在多个其他项目之间共享/使用。
在其中,我有以下组件:
/* eslint-disable react/jsx-no-useless-fragment */
import React, { Fragment } from 'react';
import type { ReactNode } from 'react';
import type { Item, ForProps } from './For.types';
const renderItem = <T extends Item>(
item: T,
children: (item: T) => ReactNode,
index: number,
itemFallback?: ReactNode
) => {
const key = Object.prototype.hasOwnProperty.call(item, 'id')
? item.id
: index;
return (
<Fragment key={key}>{children(item) || itemFallback || null}</Fragment>
);
};
function For<T extends Item>(props: ForProps<T>) {
const { each, children, fallback, itemFallback } = props;
return (
<>
{each && each.length > 0
? each.map((item, index) =>
renderItem(item, children, index, itemFallback)
)
: fallback || null}
</>
);
}
export default For;
它只是一个基本的 For
组件,是数组 map
方法的包装器,只处理缺失的键并具有回退功能。
出于某种原因,在捆绑并在我的 NextJS 项目中使用时:
import { For } from '@bidgrupa/ui';
export function ExampleComponent() {
const arr = [1, 2, 3, 4, 5];
return <For each={arr}>{num => <h1>{num}</h1>}</For>;
}
我收到以下错误:
TypeError: createContext only works in Client Components. Add the "use client" directive at the top of the file to use it. Read more: https://nextjs.org/docs/messages/context-in-server-component
因此,我决定查看一下,如果我将组件本身直接复制粘贴到 NextJS 项目中是否能正常工作,而事实证明可以!
所以我是否遗漏了什么?也许在新文档中遗漏了什么?
任何见解/帮助将不胜感激!
英文:
I am stumbling upon an issue that is a bit confusing for me.
I recently started working with new NextJS v13 that uses React server components.
I am using it in a project that relies on a small private third party library I wrote that is shared/used between multiple other project.
And inside of it I have the following component:
/* eslint-disable react/jsx-no-useless-fragment */
import React, { Fragment } from 'react';
import type { ReactNode } from 'react';
import type { Item, ForProps } from './For.types';
const renderItem = <T extends Item>(
item: T,
children: (item: T) => ReactNode,
index: number,
itemFallback?: ReactNode
) => {
const key = Object.prototype.hasOwnProperty.call(item, 'id')
? item.id
: index;
return (
<Fragment key={key}>{children(item) || itemFallback || null}</Fragment>
);
};
function For<T extends Item>(props: ForProps<T>) {
const { each, children, fallback, itemFallback } = props;
return (
<>
{each && each.length > 0
? each.map((item, index) =>
renderItem(item, children, index, itemFallback)
)
: fallback || null}
</>
);
}
export default For;
It is just a basic For
components that is a wrapper for the array map
method that just handles missing keys and has a fallback.
For whatever reason, when bundled and used in my NextJS project:
import { For } from '@bidgrupa/ui';
export function ExampleComponent() {
const arr = [1, 2, 3, 4, 5];
return <For each={arr}>{num => <h1>{num}</h1>}</For>;
}
I get the following error:
TypeError: createContext only works in Client Components. Add the "use client" directive at the top of the file to use it. Read more: https://nextjs.org/docs/messages/context-in-server-component
So I decided to see if the component itself will work if I copy and paste it inside the NextJS project directly and it worked!
So is there something I am missing? Maybe missed in new documentation?
Any insights/help would be appreciated!
答案1
得分: 0
我成功解决了这个问题。
我的情况非常特殊,但希望对使用TSDX捆绑第三方库的人有所帮助,因为只有一个导出文件的入口点,出于某种原因,react-helmet-async(尽管在我的新项目中没有使用)导致了问题。
英文:
I managed to figure out the issue.
My case was very specific but hope it helps; for whoever is using TSDX to bundle their third party libraries, because there is only one entry point for exporting files, for whatever reason react-helmet-async (although not used anywhere in my new project) was causing the issue.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论