2017-10-17 3 views
1

React, Redux, Redux-ThunkReact-Router을 사용하여 작동하는 서버 측 렌더링 솔루션을 얻는데 심각한 어려움이 있습니다.redux & react를 사용한 비동기 서버 측 렌더링

현재 나의 솔루션은 기본 지침과이 게시물 인 클라이언트 측에서 작동합니다 : 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))); 
    }; 
} 

내가 서버 측 렌더링을 필요로한다. 나는 익스프레스가 내 미들웨어 handleRender을 소비하고 차례로 renderFullPage을 호출하여 HTML 문자열을 반환합니다. Express 구현은 올 Y 른 것으로 가정 할 수 있습니다. 아래

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)); 
    }); 
} 

위의 코드를 사용하여 같은 내 handleRender 외모, Y는 콘솔에 인쇄되지만 X는 감속기 함수가 호출되지 않는 의미, 인쇄되지 않습니다. 내가 이렇게되고, 내 handleRender에 약속에서 then를 제거하면이이 handleRender 이미 HTML을 반환했을 비동기 그러나 때문에,

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

감속기 기능이 제대로 호출되고 있으며 돌아 오는 저장소는 제대로 업데이트.

도움을 주시면 감사하겠습니다. 긴 날 이었어.

+0

[next.js] (https://github.com/zeit/next.js/)를 사용하는 것이 좋습니다. repo는 많은 예제 (redux 사용 포함)를 제공하며 서버는 사용자 정의 할 수도 있습니다. – lipp

+0

처음부터 서버 측 렌더링이 필요하다는 것에 너무 늦었습니까? next.js와 redux로 프로젝트를 진행했고, 서버에서 렌더링 한 페이지를 반환하기 전에 로그인 된 사용자 계정 데이터를 가져 오는 것과 같은 일을하는 것이 엉망이었습니다. 우리는 정상적인 SPA를 구축하게되었습니다. 서버 측 렌더링은 SEO 관련 페이지 및 모바일 웹 사이트에서 초기 페이지로드를 빠르게하는 데 유용합니다. 그 외 모든 것, 특히 사용자 인증이있는 페이지의 경우에는별로 도움이되지 않습니다. – timotgl

+0

서버 측 렌더링이 필요합니다. 내가 주제에서 벗어난 SSR의 장점에 대해서는 언급하지 않겠지 만, 반응/감속을 사용 한 이후로는 그것이해야 할 것보다 훨씬 복잡하다는 느낌이 들었다. –

답변

1

환원제가itemsFetchData이 호출 된 후 으로 주입 되었기 때문에 혼란의 원인이 발생했습니다. 이 문제는 then을 사용할 때만 나타났습니다.이 요소가 없으면 감속기를 주입 한 구성 요소 Main이 여전히 포함되어 있었고 모든 것이 정상적으로 보였기 때문입니다. then에 의존했을 때 then은 퇴장을 기다리고 있었기 때문에 감속기가없고 Main 구성 요소가 포함되어 있지 않아 파견 할 수 없었습니다.

문제를 해결하기 위해 감속기를 combineReducers에 포함 시켰습니다.

내가 말했듯이, 긴 하루였습니다.

관련 문제