2017-12-21 5 views
0

Ich habe Schwierigkeiten, Server-Side-Rendering (SSR) mit redux-api zu arbeiten. Die App funktioniert nur mit clientseitigem Rendering (CSR).So erhalten Sie Next.js und Redux-API zur Arbeit (mit Next-Redux-Wrapper)

Für SSR zu arbeiten, ich brauche die Daten in Next.js’ getInitialProps Funktion zur Verfügung stehen. Ich versuche, next-redux-wrapper zu verwenden, um es zusammen zu binden.

Aktuelle Status:

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; 

ich zumindest bekommen store in getInitialProps jetzt, aber ich erhalte eine seltsame Error: only absolute urls are supported Botschaft, die ich nicht in meinem CSR habe (Vor- withRedux) Version der App. Und this.props.oneLesson.data ist natürlich leer.

makeStore bekommt einen state = undefined auf den Server generierte Anrufe, vielleicht ist das ein Hinweis.

Ich bin auch offen redux-api mit etwas anderes zu ersetzen, die in ähnlicher Weise funktioniert.

AKTUALISIEREN 1: Indem alle URLs voll sind, trifft Redux jetzt meinen API-Endpunkt. Doch für 1 Seite neu laden nennt es makeStore nicht weniger als 3 mal, und nur der erste Aufruf enthält die richtige Schnecke, siehe Konsolenausgabe:

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: Ein Durchbruch: ein Versprechen von getInitialProps macht Rückkehr SSR-Arbeit. Jetzt ist das clientseitige Rendering ziemlich lustig.

Antwort

0

Ich schaffte es zu lösen, nach einem ganzen Tag Haare ziehen.

Es gab eine Reihe von Fragen, bevor es, wie es funktioniert sollte:

  1. Absolute URLs. Der Client-only-Code hatte kein Problem mit relativen URLs, aber der Server tat es.
  2. getInitialProps muss zurückkehren ein Versprechen an den Ergebnissen (siehe unten).
  3. Mein Datenobjekt (oneLesson) endete auf this.state, nicht this.props, wie ich erwartet hatte (für meinen Anwendungsfall ist es mir nicht wirklich wichtig, solange ich es sowohl auf Server als auch auf Client rendern kann).

Hier ist die finale Version von 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; 
} 

ist das komplette Arbeitsbeispiel Next.js, redux-api und Next-redux-Wrapper arbeitet in Harmonie:

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

Verwandte Themen