我正在学习NextJS。目前,我正在使用NextJS 13和新的应用程序目录,而不是旧的页面目录。我已经尝试了各种获取数据的方法,但我没有得到任何工作。它应该像这样简单
src/app/page.tsx:
export interface ToDo {
userId: number;
id: number;
title: string;
completed: boolean;
}
const getToDos = async (): Promise<ToDo[]> => {
const res = await fetch('https://jsonplaceholder.typicode.com/todos/1');
console.log(`Status: ${res.status}`); // prints 'Status: 200'
return res.json();
}
const Home = async () => {
const toDos = await getToDos();
return (
<ul>
{toDos.map((todo) => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>
);
}
export default Home;
端点返回的JSON为
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}
这是输出。请注意我是如何得到200 OK状态和错误消息的:
Warning: Only plain objects can be passed to Client Components from Server Components. Classes or other objects with methods are not supported.
<... client={{queryCache: ..., mutationCache: ..., logger: ..., defaultOptions: ..., queryDefaults: ..., mutationDefaults: ..., mountCount: ...}} children=...>
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Warning: Only plain objects can be passed to Client Components from Server Components. Classes or other objects with methods are not supported.
{queryCache: {listeners: Set, subscribe: function, config: ..., queries: ..., queriesMap: ...}, mutationCache: ..., logger: ..., defaultOptions: ..., queryDefaults: ..., mutationDefaults: ..., mountCount: ...}
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Status: 200
- ┌ GET / 200 in 606ms
│
└──── GET https://jsonplaceholder.typicode.com/todos/1 200 in 67ms (cache: HIT)
- error node_modules/next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js (1863:12) @ resolveModelToJSON
- error Error: Functions cannot be passed directly to Client Components unless you explicitly expose it by marking it with "use server".
{listeners: Set, subscribe: function, config: ..., queries: ..., queriesMap: ...}
^^^^^^^^
at stringify (<anonymous>)
null
- error node_modules/next/dist/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js (1863:12) @ resolveModelToJSON
- error Error: Functions cannot be passed directly to Client Components unless you explicitly expose it by marking it with "use server".
{listeners: Set, subscribe: function, config: ..., queries: ..., queriesMap: ...}
^^^^^^^^
at stringify (<anonymous>)
digest: "501055159"
null
如果我在page.tsx的开头添加“use server”,我会得到一个编译错误:
Server Actions require `experimental.serverActions` option to be enabled in your Next.js config: https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions
理想情况下,我想静态生成HTML,但现在我会感谢任何工作抓取代码。
更新
我以前尝试的一个解决方案是使用Tanstack Query。我现在已经从我的layout. tsx中删除了所有这些代码。现在我得到了一个不同的错误代码:
export default async function Home(): Promise<JSX.Element> {
const todos = await getToDos();
console.log(todos);
return (
<ul>
{todos.map((todo) => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>
);
}
说
error TypeError: todos.map is not a function
2条答案
按热度按时间u4vypkhs1#
似乎你正在尝试将一个函数从服务器组件传递到客户端组件,除非它是一个服务器动作,否则这是不可能的,因为服务器动作目前仍然是一个alpha功能,你需要通过在next.config.js文件中设置
experimental.serverActions
来启用它们:下面是一个服务器端组件的示例:
我强烈建议您安装server-only包,因此如果您尝试将服务器组件导入客户端,则会抛出错误。
ql3eal8s2#
正如@FabioNettis正确指出的那样,我试图获取一个不可迭代的对象。我不小心试图从路径
/todos/1
而不是/todos
中获取。所以抓取代码实际上是正确的,尽管不是很好。良好的错误处理会使调试更容易。