umi中 SSR getInitialProps子组件使用

robin
  • 1k

该问题是他人针对 ssr 使用的疑问,在这里抛出来

问题:页面有很多公共组件,里面的接口请求也需要走SSR,但是getInitialProps在子组件无法使用

场景:那么当同一个公共组件(如nav)中的某些数据(比如nav的数量和内容是可配置的)需要通过getInitialProps获得一些服务端数据渲染之后直接返回的情况,如何收束各个页面中的公共组件数据来源呢,CSR的话可以通过在入口js或者nav的第一次载入的时机获得数据并存储到redux中,之后页面跳转时可以直接从redux中保证获得数据,整个过程无需依赖上层页面组件的参数传入,但是ssr的情况下useEffect无法触发,在通用的运行时配置(即app.tsx)里进行请求的话却不能像getInitialProps一样把返回的数据用window.g_initialData的方式传递到浏览器上,有什么办法可以让在多个组件里使用,需要的数据则是根据域名请求的组件在不依赖最外层的页面组件传入的情况下进行SSR呢

回复
阅读 736
1 个回答

关于不能在子组件中使用 getInitialProps 方法的问题,我们反向思考下,假如在子组件中使用 getInitialProps 方法会怎么样?

首先要聊一下,数据注水和脱水的问题,为了保证服务端和客户端 store 的同步,需要将服务端的
store 注入到 window 对象中(该过程叫数据注水),便于同步到客户端的 store 中(该过程叫数据脱水),避免客户端重复渲染。

回到正题,在子组件中使用 getInitialProps 方法,意味着服务端要将多个 getInitialProps 返回的数据合并成一个完整的 store 注入到 window 对象中,有几个问题:

  1. 多个 getInitialProps 执行顺序怎么处理
  2. token 如何透传到各个组件
  3. 各个 getInitialProps 返回的数据冲突了怎么处理

不要说,这不都是框架应该解决的问题嘛(写框架的也是人啊

以下是我在使用 umi 时遇到的坑:
image.png

所以还是考虑,只有容器组件能使用 getInitialProps 的情况下如何解决,公共组件数据使用的问题。

我们为 getInitialProps 实现了一个公共方法 initProps 方法:


function initProps(cb){
  return async (ctx) => {
    // 这里就可以获取公共 nav 数据
    const navs = await getNav(); 
    
    // cb 为各个模块执行的初始化操作
    const state = await cb(ctx);
    return {
       ...navs,
       ...state
    }
  }
}

Index.getInitialProps = initProps(async () =>{
  const data = await api()
  return {
    data
  }
})
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏