React如何在Server Side Rendering中預(yù)取數(shù)據(jù)(一)

不多廢話,全篇干貨。
說(shuō)SSR之前,先說(shuō)react component的一些注意點(diǎn)(這能說(shuō)明為啥我要這么預(yù)?。?/p>

  1. 盡量不要用componentWillMount
  2. 有Side Effect的操作應(yīng)該放在componentDidMount中(比如, 調(diào)用api訪問(wèn)服務(wù)器取數(shù)據(jù)就是這樣的操作)
  3. 不要再constructor里面調(diào)用setState

前兩點(diǎn)都是官方說(shuō)法,所以一定有道理。這里并不去深究,如果有興趣,可以參考這篇文章。

然而,我又不希望server端太復(fù)雜,還是盡量走react的lifecycle,所以,在組件(準(zhǔn)確地說(shuō)是container組件)的constructor中,加入了服務(wù)器端預(yù)取的邏輯(這可能不是個(gè)好的做法),然后componentDidMount放入客戶(hù)端預(yù)取的邏輯。 所以,一個(gè)component大概是這樣子的(示例代碼,僅供參考):

class SomeContainer extends Component {
  constructor(props) {
    if (typeof document === 'undefined') {
      props.dispatch(requestUserName()) // 這會(huì)觸發(fā)對(duì)服務(wù)器端的調(diào)用, 獲取數(shù)據(jù)
    }
  }

  componentDidMount() {
    if (this.props.username === "") {
      this.setState({isLoading: true})
      this.props.dispatch(requestUserName({
       callabck: () => { this.setState({isLoading: false}) } // 異步執(zhí)行, 無(wú)法放在constructor中
      }))
    }
  }
}

constructor部分做了判斷,因此只會(huì)在服務(wù)器端執(zhí)行, 而componentDidMount只會(huì)在客戶(hù)端執(zhí)行。
如果取數(shù)據(jù)的時(shí)候,不考慮setState, 那么這兩個(gè),可以合并起來(lái)放到constructor中, 從而省去componentDidMount,變成簡(jiǎn)化版:

class SomeContainer extends Component {
  constructor(props) {
    // 當(dāng)客戶(hù)端(browser)不需要setState的時(shí)候,可以合并成這個(gè)簡(jiǎn)寫(xiě)的方式
    // 如果是在客戶(hù)端其他頁(yè)面導(dǎo)航過(guò)來(lái),會(huì)執(zhí)行并取數(shù)據(jù)。
    // 如果是直接訪問(wèn)該頁(yè),服務(wù)端渲染,那么服務(wù)器端會(huì)執(zhí)行,取好數(shù)據(jù)。
    // 此時(shí)客戶(hù)端不會(huì)重新取數(shù)據(jù)了
    if (props.username === "") {
      props.dispatch(requestUserName())
    }
  }
}

代碼里面的的注釋說(shuō)得很清楚這兩個(gè)寫(xiě)法不同的用意了。

OK, 組件本身就是這樣的。不管用的是什么庫(kù)(redux-thunk, redux-saga等),我個(gè)人理解的組件的設(shè)計(jì)道理就是這樣(目的是在服務(wù)器端也幾乎完全符合于類(lèi)似于客戶(hù)端的執(zhí)行流程和邏輯, 簡(jiǎn)單點(diǎn)說(shuō),就是加個(gè)服務(wù)端渲染不用額外干太多事)。

讓我詫異的是,現(xiàn)在居然沒(méi)有一個(gè)非常官方的SSR的做法(或者是有,只是我孤陋寡聞了。。。create-react-app或者next.js在這方面有效嗎?)。

另外,吐槽一下Javascript各個(gè)庫(kù)的升級(jí),webpack、react-router這些非常流行的庫(kù)升級(jí)時(shí)居然都是向后不兼容的,本來(lái)預(yù)估的一個(gè)“簡(jiǎn)單的”升級(jí)變成了一場(chǎng)浩浩蕩蕩的代碼重構(gòu),十分操蛋。

下一篇講我如何用選定的庫(kù)在整體流程上進(jìn)行SSR實(shí)現(xiàn)的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前一篇文章講到了為了預(yù)取數(shù)據(jù),各個(gè)組件的寫(xiě)法。這里從整體上講一個(gè)client和server分別應(yīng)該怎么做。Serv...
    EagleChan閱讀 859評(píng)論 0 0
  • 原教程內(nèi)容詳見(jiàn)精益 React 學(xué)習(xí)指南,這只是我在學(xué)習(xí)過(guò)程中的一些閱讀筆記,個(gè)人覺(jué)得該教程講解深入淺出,比目前大...
    leonaxiong閱讀 2,945評(píng)論 1 18
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,281評(píng)論 25 708
  • 第二部分:文化傳承 第六章:血染哈倫 我們?cè)J(rèn)為,有類(lèi)似生活環(huán)境的人,其行為方式也與祖先類(lèi)似。然而除了目前的生活環(huán)...
    廢柴點(diǎn)不著閱讀 599評(píng)論 0 1
  • 潘岳姿容,引擲果盈車(chē),須眉東施效顰; 宋玉不凡,賦《九辨》詠傳, 品賢良惹莠嫌; 子都之姣,得廟高者識(shí),顏傳后世皆...
    草木縈心閱讀 382評(píng)論 4 3

友情鏈接更多精彩內(nèi)容