next.js 是否有办法使使用getServerSideProps呈现的页面成为非阻塞的,以便在getServerSideProps完成之前部分呈现?

6g8kf2rb  于 2022-11-23  发布在  其他
关注(0)|答案(1)|浏览(122)

我有一个非常简单的组件,可以从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]`).
5lhxktic

5lhxktic1#

我也遇到过同样的问题,但是通过在_app.js中添加一个加载器,您可以解决这个问题。

相关问题