我有一个非常简单的组件,可以从Next API获取用户。我试图使用getServerSideProps将获取从客户端移动到服务器,但我不知道如何以非阻塞的方式完成。
这是/api/users。这是一个对模拟API的简单调用,用于检索延迟中 Package 的虚拟用户。
export default function handler (
req: NextApiRequest,
res: NextApiResponse<Data>
) {
setTimeout(()=>{
(async () => {
let value = await fetch("https://jsonplaceholder.typicode.com/users");
let result = await value.json();
let data = result.slice(0,2);
console.log("API fetch result", JSON.stringify(data, null, 4));
res.status(200).json(data);
})()
}, 5000);
}
这是一个提取数据的组件
export const Users = () => {
let [users, setUsers] = useState();
useEffect(()=>{
(async () => {
let value = await fetch("/api/users");
let result = await value.json();
setUsers(result);
})()
}, []);
return <div>
<h1>header</h1>
{!users && <p>loading users</p>}
{users &&
<p className="fade-in">
users: <pre>{JSON.stringify(users, null, 4)}</pre>
</p>
}
<h2>footer</h2>
</div>
}
如果我将获取调用移到getServerSideProps并将用户传递给组件,则组件将在延迟的API调用完成之前不会呈现。当获取在客户端完成时,这不会延迟组件呈现,但在等待数据加载到getServerSideProps时延迟组件呈现是不可接受的。
这是包含getServerSideProps的修改过的Users组件。它在getServerSideProps返回之前不会呈现,因此在等待服务器端属性时,似乎无法部分呈现组件中的元素。
export const UsersFromServer = (props) => {
return <div>
<h1>header</h1>
{!users && <p>loading users</p>}
{users &&
<p className="fade-in">
users: <pre>{JSON.stringify(props.result, null, 4)}</pre>
</p>
}
<h2>footer</h2>
</div>
}
// the delayed fetch has been moved to the server
export async function getServerSideProps(context) {
let { params, req, res, query } = context;
let value = await fetch(host + "/api/users");
let result = value.json();
console.log("getServerSideProps called on the server", params, req, res, query)
return {
props: result
}
}
我对Next js是新手,所以我不确定我是否只是以错误的方式处理这个问题。有没有一种方法可以以非阻塞的方式使用getServerSideProps,以允许在(延迟的)获取完成之前部分呈现UsersFromServer?
[此处][1]的文档说明
getServerSideProps should return an object with:
*props - An optional object with the props that will be received by the page component. It should be a serializable object or a Promise that resolves to a serializable object.*
我尝试重新编码getServerSideProps以返回一个承诺,但这导致了一个错误。
export async function getServerSideProps(context) {
let { params, req, res, query } = context;
// let value = await fetch(host + "/api/users");
// let result = await value.json();
// console.log("getServerSideProps called on the server", params, req, res, query)
// return {
// props: {result}
// }
let propsPromise = fetch(host + "/api/users").then((value)=>{
value.json().then((result)=>{
return {
props: {result}
}
})
})
return {props: propsPromise};
}
错误:
Server Error
Error: Error serializing props returned from `getServerSideProps` in "/ssr".
Reason: Props must be returned as a plain object from getServerSideProps: `{ props: { ... } }` (received: `[object Undefined]`).
1条答案
按热度按时间5lhxktic1#
我也遇到过同样的问题,但是通过在_app.js中添加一个加载器,您可以解决这个问题。