1

我正在努力让服务器端渲染 (SSR) 与redux-api. 该应用程序仅适用于客户端渲染 (CSR)。

要使 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;

我至少现在store进入getInitialProps了,但我收到了一条奇怪的Error: only absolute urls are supported消息,我的 CSR(pre- withRedux)版本的应用程序中没有。当然this.props.oneLesson.data是空的。

makeStore在服务器生成的调用上得到一个state= undefined,也许这是一个线索。

我也愿意用redux-api其他类似的东西代替。

更新 1:通过使所有 URL 都填满,Redux 现在正在访问我的 API 端点。但是,对于 1 页重新加载,它调用makeStore不少于 3 次,并且只有第一个调用包含正确的 slug,请参阅控制台输出:

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' }

更新 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;
}
4

1 回答 1

2

经过一整天的拉扯,我设法解决了这个问题。

在它应有的工作之前存在许多问题:

  1. 绝对网址。仅客户端代码对相对 URL 没有问题,但服务器有。
  2. getInitialProps必须向结果返回一个 Promise(见下文)。
  3. 我的数据对象 ( oneLesson) 最终出现在 上this.state,而不是this.props像我预期的那样(对于我的用例,只要我可以在服务器和客户端上都呈现它,我并不在意)。

这是 的最终版本getInitialProps

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 和 next-redux-wrapper 协调工作的完整工作示例:

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

于 2017-12-21T20:13:22.863 回答