2017-12-21 18 views
0

サーバサイドレンダリング(SSR)をredux-apiと連携させるのは苦労しています。このアプリケーションは、クライアント側のレンダリング(CSR)だけで正常に動作します。Next.jsとredux-apiを動作させる方法(next-redux-wrapperを使用)

SSRが機能するには、Next.jsのgetInitialProps機能でデータを利用できるようにする必要があります。私はそれを一緒にバインドするためにnext-redux-wrapperを使用しようとしています。

現状は:

class ShowLessonPage extends React.Component { 

    static async getInitialProps ({store, isServer, pathname, query}) { 
     console.log(`getInitialProps`, {store, isServer, pathname, query}); 
     const { dispatch } = store; 
     const lessonSlug = query.lessonSlug; 
     // Get one Lesson 
     dispatch(reduxApi.actions.oneLesson({ id: `slug=${lessonSlug}` })); 
    } 

    render() { 
     console.log('render', this.props.oneLesson); 
     const lesson = this.props.oneLesson.data; 
     //... 
    } 

    //..... 

} 

const createStoreWithThunkMiddleware = applyMiddleware(thunk)(createStore); 
const reducer = combineReducers(myReduxApi.reducers); // redux-api 

const makeStore = function (state, enhancer) { 
    return createStoreWithThunkMiddleware(reducer, state); 
} 

const mapStateToProps = function (state) { 
    return { oneLesson: state.oneLesson }; 
}; 

// withRedux = next-redux-wrapper 
const ShowLessonPageConnected = withRedux({ createStore: makeStore, mapStateToProps: mapStateToProps })(ShowLessonPage) 
export default ShowLessonPageConnected; 

私は少なくとも今getInitialPropsstoreを得るが、私は私が私のCSRアプリの(前withRedux)のバージョンではありませんでした奇妙なError: only absolute urls are supportedメッセージが表示されます。もちろんthis.props.oneLesson.dataは空です。

makeStoreがサーバで生成されたコールでstate = undefinedになっている可能性があります。

私はまた、redux-apiを同様に動作するものに置き換えています。

UPDATE 1:すべてのURLをいっぱいにすることで、Reduxは現在APIエンドポイントにヒットしています。コンソール出力を参照してください。ただし、1ページのリロードのためにはmakeStore劣らず3倍を呼び出し、唯一の最初の呼び出しが正しいスラグが含まれています

makeStore { state: undefined, reqParams: { lessonSlug: 'tyrannosaurus-rex' } } 
getInitialProps { query: { lessonSlug: 'tyrannosaurus-rex' } } 
API: GET request: { _id: 'slug=tyrannosaurus-rex' } 
makeStore { state: undefined, reqParams: { lessonSlug: 'undefined' } } 
getInitialProps { query: { lessonSlug: 'undefined' } } 
API: GET request: { _id: 'slug=undefined' } 
makeStore { state: undefined, reqParams: { lessonSlug: 'undefined' } } 
getInitialProps { query: { lessonSlug: 'undefined' } } 
API: GET request: { _id: 'slug=undefined' } 

UPDATEを2:突破口:getInitialPropsますから約束を返しますSSRの仕事。クライアント側のレンダリングが面白くなりました。

static async getInitialProps ({store, isServer, pathname, query}) { 
    const { dispatch } = store; 
    const lessonSlug = query.lessonSlug; 
    const resultPromise = await dispatch(reduxApi.actions.oneLesson({ id: `slug=${lessonSlug}` })); 
    return resultPromise; 
} 

答えて

0

私は一日の髪引っ張った後、それを解決するために管理。

  1. 絶対URL:それはそれが必要として働いていた前

    は多くの問題がありました。クライアント専用のコードでは、相対URLに問題はありませんでしたが、サーバーでは問題ありませんでした。

  2. getInitialPropsは、プロミスを結果に返す必要があります(下記参照)。
  3. データオブジェクト(oneLesson)がthis.stateになりました。私は期待通りにはthis.propsではありませんでした。(私の使用例では、サーバーとクライアントの両方でレンダリングできる限り、本当に気にしません)。ここで

    static async getInitialProps ({store, isServer, pathname, query}) { 
        const { dispatch } = store; 
        const lessonSlug = query.lessonSlug; 
        const resultPromise = await dispatch(reduxApi.actions.oneLesson({ id: `slug=${lessonSlug}` })); 
        return resultPromise; 
    } 
    

    Next.js、Reduxの-APIの完全な作業例だ、と次Reduxのラッパーが調和して働く:

ここgetInitialPropsの最終版です

https://github.com/tomsoderlund/nextjs-express-mongoose-crudify-boilerplate

関連する問題