ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • react - next 프레임워크를 활용해 ssr(server side rendering) 간단히 해결
    WEB/react 2019. 8. 20. 03:06
    728x90

    server side rendering을 next의 getInitialProps를 활용해 간단하게 해결해보자.

    redux와 redux-saga를 활용해 문제를 해결한다.

    다양한 액션 중 블로그에서 포스팅한 글들을 프론트 서버에서 백엔드 서버로 요청하는 것을 해보자.

    pages 폴더의 _app.js 에서 useEffect를 활용해 dispatch를 한다고 하면

    1. next와 redux-saga를 연결할 패키지를 다운 받는다

    npm i next-redux-saga
    npm i next-redux-wrapper
    npm i redux-saga

    2. saga를 config 하자.

    (_app.js) 파일
    import rootSaga from './saga.js' // saga를 지정해 놓은 파일
    import withRedux from 'next-redux-wrapper' //next와 redux의 미들웨어( 여기서는 saga)를 연결
    import withReduxSaga from 'next-redux-saga'
    import createSagaMiddleware from 'redux-saga'
    ///대충
    ///redux관련
    
    const App = ({Component, store, pageProps}) =>{
        //대충 redux 관련 코드, 모든 페이지에 적용할 코드 들 (ex Provider로 store 건내주기)
    }
    
    //...
    //대충 propTypes 관련 코드
    //...
    
    App.getInitialProps = async (context) => {
        let pageProps = {}
        const {ctx, Component} = context //ctx는 프론트 서버가 실행하면서 next가 context를 전달해줌.
        const state = ctx.store.getState() // redux의 store에서 state를 getState를 통해 꺼내온다
        ctx.store.dispatch({
            type: LOAD_POST_REQUEST //포스팅한 글들을 reducer를 이용한 dispatch
        })
        pageProps = await Component.getInitialProps(ctx)
        return pageProps
    }
    
    const storeConfig = (initialState, options) =>{
        const sagaMiddleware = createSagaMiddleWare()
        const middlewares = [sagaMiddleware] //middleware들 다 여기로 모여라~
        const enhancer = process.env.NODE_ENV === 'production'
        ? compose(applyMiddleware(...middlewares))
        : compose(
          applyMiddleware(...middlewares),
          !options.isServer && typeof window.__REDUX_DEVTOOLS_EXTENSION__ !== 'undefined' ? window.__REDUX_DEVTOOLS_EXTENSION__() : f => f,
        ) // chrome redux devtools 에 대한 설정. (redux devtools를 개발모드에서만 사용하고 싶어요 라는 내용)
      const store = createStore(reducer, initialState, enhancer);
      store.sagaTask = sagaMiddleware.run(rootSaga);
      return store;
    }
    
    
    export default withRedux(storeConfig)(withReduxSaga(App))

    그런데, withcredential 옵션을 사용할때 쿠키를 넣어주어야 한다면은

    App.getInitialProps = async (context) => {
        let pageProps = {}
        const {ctx, Component} = context //ctx는 프론트 서버가 실행하면서 next가 context를 전달해줌.
        const state = ctx.store.getState() // redux의 store에서 state를 getState를 통해 꺼내온다
        const cookie = ctx.isServer ? ctx.req.headers.cookie : '' // 서버에서 요청할때 ctx에 req객체가 붙는다.
        if(ctx.isServer &&cookie){
            axios.defaults.headers.cookie = cookie
        }
        ctx.store.dispatch({
            type: LOAD_POST_REQUEST //포스팅한 글들을 reducer를 이용한 dispatch
        })
        pageProps = await Component.getInitialProps(ctx)
        return pageProps
    }
    

    +추가

    storeConfig 에서 getInitialProps의 action을 로깅해주는 커스텀 미들웨어를 만들어보자

    const storeConfig = (initialState, options) =>{
        const sagaMiddleware = createSagaMiddleWare()
        const middlewares = [sagaMiddleware, (store)=>(next)=>(action)=>{
            console.log(store)
            next(action)
        }] // 커스텀 미들웨어
        const enhancer = process.env.NODE_ENV === 'production'
        ? compose(applyMiddleware(...middlewares))
        : compose(
          applyMiddleware(...middlewares),
          !options.isServer && typeof window.__REDUX_DEVTOOLS_EXTENSION__ !== 'undefined' ? window.__REDUX_DEVTOOLS_EXTENSION__() : f => f,
        ) // chrome redux devtools 에 대한 설정. (redux devtools를 개발모드에서만 사용하고 싶어요 라는 내용)
      const store = createStore(reducer, initialState, enhancer);
      store.sagaTask = sagaMiddleware.run(rootSaga);
      return store;
    }

    'WEB > react' 카테고리의 다른 글

    react-next pagination 구현  (0) 2019.08.22

    댓글

Designed by Tistory.