next.js 使用React Server组件提取数据:这是正确实现吗?

0sgqnhkj  于 2022-11-05  发布在  React
关注(0)|答案(2)|浏览(163)

我在一个应用程序中使用Next.JS,其中有一个Navbar组件,该组件在应用程序的所有页面上都需要,并且Navbar呈现必须从我的数据库中获取的数据(特别是product-categories)。
我希望在服务器端呈现此组件,但由于Next.JS只支持页面级SSR,而不支持组件级SSR,因此似乎必须在所有希望显示此Navbar的页面上使用getServerSideProps,并在每个页面中编写相同的API请求,从而导致在多个页面上重复大量的逻辑和API调用。
在研究如何解决这个问题时,我遇到了React Server Components,并想知道它是否是此场景的有效解决方案,但由于我对这个概念是新的,我不确定我是否正确理解了它,因此我写了这个问题。
我正在考虑做以下事情,并希望得到一些反馈,以确定我是否走在正确的道路上。
我的导航栏组件将如下所示:

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组件,以便Navbar包含在所有页面中,这也是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 Components的优势之一吗?

bvjveswy

bvjveswy1#

现在有了Next.JS13版本,您可以创建一个默认使用react服务器组件的app目录。
但是您应该记住,大多数React钩子(如useState和useEffect)在服务器组件上不起作用,而且以前的Next.js API(如getServerSideProps、getStaticProps和getInitialProps)在新的应用程序目录中也不受支持。
因此,您可以使用新的fetch()API,该API构建在本机fetch()Web API.Check the docs for more details之上。

bwleehnv

bwleehnv2#

你可以在_app.tsx中使用SSR来代替通过API获取数据,SSR将数据作为props传递给MyApp钩子,然后数据可以进一步传递给Layout组件,Layout组件再将数据进一步传递给Navbar组件。因此,它看起来像这样:
第一个
编辑:SSR在_app.tsx中不起作用,但我在这里找到了答案:https://stackoverflow.com/a/72325973/12190941
编辑2:如果您希望整个站点在服务器端呈现,可以在_app.js中使用getInitalProps。请记住,这将增加初始加载时间。我在Next.js docs here中找到了这个示例

// _app.js

// ...

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

   return { ...appProps }

相关问题