React + React-Loadable 实现服务端渲染

项目地址:react-ssr-demo

服务端渲染一般在活动页或者官网项目有用到,有利于SEO和首屏渲染优化。

项目用到React-Loadable实现异步加载,在服务端渲染时需要对异步加载的组件进行处理实现同步读取数据。

附上异步组件代码

class List extends Component {

  constructor(props) {
    super(props)
  }

  static fetchData = async (props, params = {}) => {
    await props.dispatch(getArticleList(params))
  }

  componentDidMount() {
    if (!this.props.result) {
      const { params = {} } = this.props.match || {}
      this.constructor.fetchData(this.props, params)
    }
  }

  render() {
    const { result = [] } = this.props
    return (
      <div className="article-page">
        {
          result.map(({ id, createTime, title }) => (
            <div key={id}>{title}---{createTime}</div>
          ))
        }
        <Button type="primary">测试</Button>
      </div>
    )
  }
}
复制代码

因为服务端是没有componentDidMount方法的,所以添加静态方法fetchData获取接口数据,当服务端渲染时,匹配到当前路由组件后则调用fetchData方法,将数据写入redux。在单页渲染时则直接从componentDidMount获取即可。

服务端渲染核心代码

export default async (req, res, next) => {
  //fetch data before component render

  const matchedComponents = matchRoutes(routes, req.url).map(({ route }) => {
    if (!route.component.preload) { // 同步组件
      return route.component;
    } else { // 异步组件
      return route.component.preload().then(res => res.default)
    }
  })
  const loadedComponents = await Promise.all(matchedComponents);

  const promises = loadedComponents.map(component => {
    return component.fetchData ? (component.fetchData(store, req.params || {})) : Promise.resolve(null)
  })
  await Promise.all(promises).catch(err => console.log('err:---', err))

  //匹配路由
  if (getMatch(routes, req.url)) {
    const context = await renderHtml(req, store)
    res.send(context)
  } else {
    await next()
  }
}

复制代码

异步组件主要是通过React-Loadablepreload方法获取组件,然后用Promise.all统一获取数据填充到html即可

转载于:https://juejin.im/post/5c41da82e51d455249761932

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值