使用 React Server 组件获取数据:这是一个正确的实现吗?



我正在使用Next.JS在一个应用程序中,我有一个应用程序的所有页面上都需要的Navbar组件,并且Navbar呈现必须从我的数据库中获取的数据(特别是product-categories)。

我希望这个组件是服务器端渲染的,但由于 Next.JS 只支持页面级 SSR 而不是组件级 SSR,因此似乎我必须在要显示此Navbar的所有页面上使用getServerSideProps并在每个页面上编写相同的 API 请求,导致跨多个页面的大量重复逻辑和 API 调用。

在研究如何解决这个问题时,我遇到了 React Server 组件,想知道这是否是这种情况的有效解决方案,但由于我是这个概念的新手,我不确定我是否正确理解它,因此我为什么要写这个问题。

我正在考虑执行以下操作,并希望获得一些关于我是否走在正确轨道上的反馈。

我的导航栏组件如下所示:

const Navbar = () => {
const [data, setData] = useState();
useEffect(() => {
fetchData();
}, []);
const fetchData = async () => {
const data = await fetch("/api/someEndpoint");
setData(data);
};
return (
<div>
{data.someProperty}
{data.someOtherProperty}
</div>
);
};
export default Navbar;

然后我可以创建一个全局Layout组件,以便导航栏包含在所有页面中,这是使用React.Suspense的地方(如果我理解正确的话):

const Layout = ({ children }) => {
return (
<>
<React.Suspense fallback={<FallbackComponent />}>
<Navbar />
<React.Suspense />
{children}
</>
);
};
export default Layout;

然后在_app.tsx中,我将包含我的Layout组件,以便Navbar无处不在:

function MyApp({ Component, pageProps: { session, ...pageProps } }: AppProps) {
return (
<Layout>
<Component {...pageProps} />
</Layout>
);
}

所以我的问题来了:这是一个正确的实现和有效的React.Suspense用例吗?组件级数据获取是 React Server 组件的建议优势之一吗?

现在使用Next.JS 13 版本,您可以创建一个默认使用 react 服务器组件的应用程序目录。

但是你应该记住,大多数 React 钩子(如 useState 和 useEffect)不适用于服务器组件,之前的 Next.js API 如 getServerSideProps、getStaticProps 和 getInitialProps 在新的应用目录中也不受支持。

因此,您可以使用基于本机 fetch() Web API 构建的新 fetch() API。查看文档以获取更多详细信息。

您可以在_app.tsx中使用 SSR 将数据作为 props 传递给MyApp钩子,而不是通过 API 获取。然后,数据可以进一步传递到Layout组件中,该组件将再次将其进一步传递到Navbar组件。所以它看起来像这样:

// _app.tsx
function MyApp({ /* Props */, data }) {
return (
<Layout data={data}>
<Component {...pageProps} />
</Layout>
);
}
export function getServerSideProps(context) {
// Get data
return {
props: {
data: data
},
}
}
// Layout.tsx
const Layout = ({ children, data }) => {
return (
<>
<Navbar data={data} />
{children}
</>
);
};
export default Layout;
// Navbar.tsx
const Navbar = ({ data }) => {
return (
<div>
{data.someProperty}
{data.someOtherProperty}
</div>
);
};
export default Navbar;

编辑:_app.tsx中的SSR不起作用,但我在这里找到了答案:https://stackoverflow.com/a/72325973/12190941

编辑2: 如果您希望整个站点在服务器端呈现,则可以在_app.js中使用getInitalProps。请记住,这将增加初始加载时间。我在下面的.js文档中找到了这个例子

// _app.js
// ...
MyApp.getInitialProps = async (appContext) => {
// calls page's `getInitialProps` and fills `appProps.pageProps`
const appProps = await App.getInitialProps(appContext);
return { ...appProps }

相关内容

最新更新