React Server Component 在我看来不是一个好的设计,为了解决一个简单问题的问题引入了更多概念和复杂度。
最初 RSC 要解决的简单问题是:在服务端渲染时如何请求数据?
由于 React hooks 令人费解的设计哲学,React 传统组件无法异步。在客户端渲染时,一般通过 `useEffect` 来获取数据。而在服务端渲染时,我们无法使用 `useEffect`,这使得在服务端请求数据(以及其他异步操作)成为了一个问题。顺带一提,vue3(nuxt.js) 就不会面临这个问题,因为 vue3 的组合式 API 没有 React hooks 的一堆限制,并且 setup 是能够异步的。
Next.js(RSC)给出的答案是:设计一个全新的服务端组件,专门用来在服务端发请求。好处是,这个组件可以异步了,坏处是,在这个组件中无法使用 hooks 。
Remix(React-Router-v7)的答案是:Loader 。预先定义好要加载的数据,框架会在数据加载完后将数据注入到组件中。
在我看来 Loader 方案明显比 RSC 更好:
1. 性能更好:Loader 单次加载完成页面所有数据; RSC 每次加载一个组件,加载完父组件的数据,再加载子组件的数据。
2. 更低的心智负担:Loader 只需要提前写好请求,然后方便地通过 useLoaderData 拿到数据; RSC 则引入了额外的服务端组件的概念,在编写时得区分是否为服务端组件,还得到处写 "use client"。
包括新出的 TanStack 也是提倡使用 Loader 方案而不是 RSC 。
参考:
https://react.dev/blog/2020/12/21/data-fetching-with-react-server-componentshttps://nuxt.com/docs/getting-started/data-fetchinghttps://remix.run/docs/en/main/discussion/data-flowhttps://tanstack.com/router/latest/docs/framework/react/guide/data-loading