2017-10-17 113 views
1

我很難得到一個工作服務器端渲染解決方案使用React,Redux,Redux-ThunkReact-Router異步服務器端渲染使用REDX和反應

目前,我的解決方案在客戶端遵循以下基本準則和本文:https://codepen.io/stowball/post/a-dummy-s-guide-to-redux-and-thunk-in-react。爲了簡化,我將使用該博客中的代碼作爲示例。唯一的變化是我添加了一個console.log("X");到減速功能items,以便我知道它何時被調用。得到的功能是:

export function items(state = [], action) { 
    switch (action.type) { 
     case 'ITEMS_FETCH_DATA_SUCCESS': 
      console.log('X'); 
      return action.items; 

     default: 
      return state; 
    } 
} 

,我還設置了itemsFetchData函數返回的承諾,成爲:

export function itemsFetchData(url) { 
    return (dispatch) => { 
     dispatch(itemsIsLoading(true)); 

     return fetch(url) 
      .then((response) => { 
       if (!response.ok) { 
        throw Error(response.statusText); 
       } 

       dispatch(itemsIsLoading(false)); 

       return response; 
      }) 
      .then((response) => response.json()) 
      .then((items) => dispatch(itemsFetchDataSuccess(items))) 
      .catch(() => dispatch(itemsHasErrored(true))); 
    }; 
} 

,因爲我需要服務器端呈現。我安裝了Express來使用我的中間件handleRender,後者又調用返回HTML字符串的renderFullPage。 Express實現可以假定爲正確的。我handleRender看起來像下面

export function handleRender(req, res) { 
    // Create a new Redux store instance 
    const store = configureStore(); 

    const { dispatch } = store; 

    dispatch(itemsFetchData(''http://5826ed963900d612000138bd.mockapi.io/items'')).then(() => { 
    console.log("Y"); 
    // Render the component to a string 
    const html = renderToString(
     <Provider store={store}> 
     <div id="app"> 
      <StaticRouter context={{}} location={req.url}> 
      <Main /> 
      </StaticRouter> 
     </div> 
     </Provider> 
    ); 

    // Grab the initial state from our Redux store 
    const preloadedState = store.getState(); 

    // Send the rendered page back to the client 
    res.send(renderFullPage(html, preloadedState)); 
    }); 
} 

使用上面的代碼,Y被打印到控制檯,但X從不打印,這意味着減速功能不會被調用。如果我刪除自許的then在我handleRender,從而成爲:

dispatch(itemsFetchData(''http://5826ed963900d612000138bd.mockapi.io/items'')); 
console.log("Y"); 
// ... remaining code remains unaltered 

的減速功能的調用是否正確和終極版店內正確更新,但由於這是異步的handleRender早就返回的HTML。

任何幫助將不勝感激。這是一個漫長的一天。

+0

我建議使用[next.js](https://github.com/zeit/next.js/)。回購提供了許多例子(包括使用redux),服務器也是可定製的。 – lipp

+0

現在挑戰服務器端渲染的要求是否太遲了?我使用next.js和redux工作了一個項目,並且在返回服務器呈現的頁面之前執行諸如獲取登錄的用戶帳戶數據之類的東西是一種痛苦。我們最終建立了一個正常的SPA。 服務器端渲染很適合搜索引擎優化相關頁面和移動網站,以加快初始頁面加載。對於其他所有內容,尤其是使用用戶身份驗證的頁面,這不是很有益。 – timotgl

+0

服務器端渲染是一項要求。我不會談論SSR的優點,因爲它與主題無關,但我同意,由於使用react/redux感覺它比它應該/過去要複雜得多。 –

回答

1

造成混淆的原因是因爲在之後注入了還原劑而調用了itemsFetchData。只有在使用then時才注意到問題,因爲沒有它,注入減速器的組件Main仍然包含在內,並且一切看起來都很正常。當它依靠then我最終以then無法發送,因爲沒有減速器和Main組件不包括在內,因爲它正在等待發送。

爲了解決這個問題,我在我的combineReducers中加入了減速器。

就像我說的那樣,這是漫長的一天。

相關問題