在Next.JS中组合服务器组件和客户端组件

huangapple go评论82阅读模式
英文:

Combining Server Components and Client Components in Next.JS

问题

我在一个Next.JS应用中遇到了一些问题。

这个应用已经有一些服务器组件按照我期望的方式运行。
这些组件允许我从数据库中获取数据。

以下是主要组件的代码:

export default async function SentenceList({}:{}) {
    const theResult = await sentences()

    return <div>
        {
            theResult.map(item => (
                <div key={item.orderKey as string}>
                    <SentenceUnit sentence={item.sentence}
                                  english={item.english}
                                  french={item.french} />
                </div>
            ))
        }
    </div>
} /* End of SentenceList */

到目前为止一切都正常。问题从这里开始。

我想以几种不同的方式调用上面的组件(传递参数)。换句话说,它会变成这样:

export default async function SentenceList(
    {param}:{param: number}) {
    ... 根据param的值进行处理 ...
} /* End of SentenceList */

但为了允许用户设置要传递给此服务器组件的参数的值,我需要一个客户端组件来设置交互以获取用户输入。这就是问题所在。

我尝试设置一个客户端组件(请参阅下面的代码),从中我可以获取用户输入并调用我的工作服务器组件。但它不起作用(至少我这样做的方式不起作用)。

'use client'
......

export default function SentenceDisplayMng() {
    const [transType, setTransType] = useState(1)
    const [typeChecks, setTypeChecks] = useState([false,false])

    return <div>
        <TranslatChoice
                    actionFunc={(v) => setTransType(v)} 
                    radChecks={typeChecks} />
        
        <SentenceList />
    </div>
} /* End of SentenceDisplayMng */

由于存在useState,我必须设置:'use client'。

但一旦我这样做,我被告知我不能这样做。确切地说,我收到以下错误消息:

Unhandled Runtime Error

Error: async/await is not yet supported in Client Components, only Server Components. This error is often caused by accidentally adding 'use client' to a module that was originally written for the server.

这里确实已经添加了'use client'(到客户端组件),但这并不是偶然的。

F.Y.I. 在上面的代码中,TranslatChoice只是一个通过单选框获取用户信息的组件,但这与问题无关。

我尝试做的事情足够基础,以至于其他人肯定也会在我之前遇到相同的问题,必须有一个相当简单的解决方案。我是不是以错误的方式将服务器组件包含在客户端组件中?还有没有更好的方法?

我希望一些Next.JS专家能够给我一些好的建议。

英文:

I am facing some issue in a Next.JS app.

This app has some server components already functionning as I expect.
Those components allow me to fetch data from a database.

Here is the code for the main component:

export default async function SentenceList({}:{}) {
	const theResult = await sentences()

	return &lt;div&gt;
		{
			theResult.map(item =&gt; (
				&lt;div key={item.orderKey as string}&gt;
					&lt;SentenceUnit sentence={item.sentence}
												english={item.english}
												french={item.french} /&gt;
				&lt;/div&gt;
			))
		}
	&lt;/div&gt;
} /* End of SentenceList */

Up to this point all is fine. Problems come from now on.

I want to call the component above in a few various ways (passing it parameters). In other words it would become:

	export default async function SentenceList(
		{param}:{param: number}) {
		... work according to value of param ...
	} /* End of SentenceList */

But to allow the user to set the value of the parameter to be passed to this server component I need a client component to set interactity to get the user input. And this is where troubles come.

I have tried to set a client component (see code below) from where I could get the user input and also call my working server component. But it does not work (at least, the way I do it).

	&#39;use client&#39;
	.....

	export default function SentenceDisplayMng() {
		const [transType, setTransType] = useState(1)
		const [typeChecks, setTypeChecks] = useState([false,false])

		return &lt;div&gt;
	      &lt;TranslatChoice
					actionFunc={(v) =&gt; setTransType(v)} 
					radChecks={typeChecks} /&gt;

	        &lt;SentenceList /&gt;
		&lt;/div&gt;
	} /* End of SentenceDisplayMng */

Because of the presence of useState I have to set: 'use client'

But once I do that I am told that I cannot do such a thing. Precisely I get this error message:

Unhandled Runtime Error

Error: async/await is not yet supported in Client Components, only Server Components. This error is often caused by accidentally adding `&#39;use client&#39;` to a module that was originally written for the server.

Here 'use client' has indeed been added (to the Client Component), but that was not accidental.

F.Y.I. In the code above TranslatChoice is just a component made to get the user information via radio boxes, but this is rather irrelevant to the question.

What I am trying to do is basic enough so that other people are bound to have met the same issue before me and there must be a reasonably easy solution. Am I including the Server Components inside the Client Components in a wrong manner? Or is there some better way to do?

I hope some Next.JS expert will be able to give me some good tips here.

答案1

得分: 2

你不能将服务器组件直接作为客户端组件的子组件添加,至少不能这样做。你可以将服务器组件作为属性传递给客户端组件,但客户端组件的父级必须是服务器组件。你可以在文档中了解更多信息 Next.js文档

英文:

You can't add a server component as a child to client component, at least not like this. You can pass the server component as prop to client component but the parent of client component needs to be a server component. You can read more about it in the docs Nextjs docs.

huangapple
  • 本文由 发表于 2023年7月17日 16:23:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/76702650.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定