为什么我不能在 Next.js 13 的子组件中使用“useState”?

Why I cannot use `useState` in a child component in Next.js 13?

提问人:alEN 提问时间:5/8/2023 最后编辑:yuriy636alEN 更新时间:6/30/2023 访问量:6273

问:

NextJS 中的新更新出来了(带有应用程序路由器)。我对客户端/服务器端组件关系感到非常困惑。我目前正在试验它,它在文档中说:

“使用客户端”位于仅服务器代码和客户端代码之间。它被放置在 文件顶部,在导入上方,以定义其截止点 跨越从仅服务器到客户端部分的边界。一次 “use client”是在文件中定义的,导入其中的所有其他模块(包括子组件)都被视为客户端捆绑包的一部分。

现在,这是我的代码 (Child.tsx):

import Parent from "./Parent";
import React, { useState } from 'react';

export default function Child() {
    const [s, ss] = useState(null);

    return (
        <div>child</div>
    )
}

父.tsx

'use client';
import React, { useState } from 'react'

export default function Parent({children} : {
    children: React.ReactNode
}) {
    const [s, ss] = useState(null);

    return (
        <div>{children}</div>
    )
}

page.tsx

import Child from "./Child";
import Parent from "./Parent";

export default function Page() {

  return (
    <>
      <Parent>
        <Child />
      </Parent>
    </>
  )
}

由于我的父组件具有“use client”指令,因此根据文档,所有子组件也必须标记为客户端组件:

./app\Child.tsx

ReactServerComponents错误:

您正在导入 需要 useState 的组件。它仅适用于客户端组件,但 它的父级都没有标记为“使用客户端”,因此它们是服务器 默认为组件。

此问题的原因是什么?

reactjs next.js 客户端 next.js13 react-server-components

评论

2赞 wongz 5/8/2023
如果你的组件使用任何类型的状态,它必须有“use client”。我认为您可能会假设,如果父级有“使用客户端”,那么所有子级都会自动成为“使用客户端”,但事实并非如此。您需要为每个文件指定它。在这种情况下,每当您在文件中使用“useEffect”和“useState”作为开始时,请添加“use client”行
0赞 Youssouf Oumar 5/8/2023
当他们说包括子组件时,他们谈论的是该组件内部调用的组件,而不是由它包装的组件,被 .这就是为什么客户端组件可以是服务器组件的原因。childrenchildren

答:

1赞 alexortizl 5/8/2023 #1

我认为在这种情况下,Next.js文档有些误导。在您的案例中发生的情况是,默认情况下,两者都被定义为服务器组件,在这种情况下,它被呈现为客户端,因为它具有指令,但被呈现为服务器组件,因为它是在服务器组件 (page.tsx) 中声明的,并且没有指令。所有效果都是服务器组件,因此它不能使用 .另一种看待这个问题的方法是,在其属性中获取的是已经呈现为page.tsx中的服务器组件的组件(html和css),而不是要与一起呈现的组件声明。实际上,将服务器组件作为子组件传递给另一个服务器组件中的客户端组件是将服务器组件置于客户端组件中的唯一方法。我知道这可能很难让你理解,我建议看看他们 https://nextjs.org/docs/getting-started/react-essentials#importing-server-into-client-components 有一些很好的例子。<Parent /><Child />page.tsx<Parent />'use client'Child'use client'<Child />useState<Parent />children<Child /><Child /><Parent />

1赞 Pouya 6/27/2023 #2

你需要在代码的顶部添加,然后从 React 导入 AND :"use client"useStateReact

"use client"

import { React , useState } from 'react';

对于您正在使用状态的所有页面,它都是必需的,否则它将不起作用。