Gatsby能否服务端渲染外部API数据?实现页面预填充
当然可以实现!你之前在constructor或componentDidMount里请求数据的方式是客户端渲染,所以只有等浏览器加载完JS后才会获取数据并渲染。Gatsby提供了专门的API,能让你在**构建阶段(静态生成)或用户请求阶段(服务端渲染)**提前获取外部数据,把内容预填充到HTML里,用户打开页面就能看到完整内容——完全不用依赖GraphQL。
下面分两种场景给你具体实现方案:
场景1:数据不常更新,用静态生成(推荐)
如果你的外部API数据更新频率低,比如一天更一次,用getStaticProps最合适。这个函数会在Gatsby构建(gatsby build)的时候运行,把数据预渲染到静态HTML中,性能最优。
实现步骤:
在src/pages下创建页面组件(比如posts.js),代码示例:
import React from "react"; import axios from "axios"; // 页面组件,直接接收预获取的数据作为props const PostsPage = ({ posts }) => { return ( <div> <h1>所有文章</h1> <ul> {posts.map((post) => ( <li key={post.id}>{post.title}</li> ))} </ul> </div> ); }; // 关键:导出getStaticProps函数,在构建时获取数据 export async function getStaticProps() { // 用async/await请求外部API const response = await axios.get("http://jsonplaceholder.typicode.com/posts"); const posts = response.data; // 返回数据,作为props传给页面组件 return { props: { posts, }, // 可选:如果需要定时重新生成页面,设置revalidate(单位秒) // revalidate: 86400, // 每天重新生成一次 }; } export default PostsPage;
运行gatsby build后,打开生成的HTML文件,你会看到文章列表已经直接写在HTML里了,浏览器加载时不用等JS执行就能看到内容。
场景2:数据实时更新,用服务端渲染
如果你的API数据会频繁变化,需要每次用户访问页面时都获取最新数据,就用getServerSideProps。这个函数会在每次用户请求页面时在服务端运行,获取最新数据后再渲染页面返回给浏览器。
实现步骤:
把上面的getStaticProps换成getServerSideProps即可,代码几乎一样:
// 页面组件和上面一致,省略... // 换成getServerSideProps,每次请求都执行 export async function getServerSideProps() { const response = await axios.get("http://jsonplaceholder.typicode.com/posts"); const posts = response.data; return { props: { posts, }, }; } export default PostsPage;
运行gatsby develop或者gatsby serve后,每次刷新页面,服务端都会重新请求API获取最新数据,然后把渲染好的HTML返回给浏览器。
注意事项
- 这两个API只能在
src/pages目录下的页面组件中使用,如果是子组件需要数据,你可以从页面组件把props传下去。 - 如果你用的是Gatsby v4及以上版本,这两个API都是原生支持的,不用额外安装插件。
- 不用担心跨域问题,因为
getStaticProps和getServerSideProps都是在服务端/构建环境运行的,不是在浏览器里发起请求,所以不存在跨域限制。
这样就能完美实现你想要的效果:页面加载时内容已经预填充,不用等客户端JS请求数据啦!
内容的提问来源于stack exchange,提问作者Łukasz Blaszyński

