-1

私のアプリケーション(SSRブランチを使用)にreact-boilerplateを使用しています。何らかの理由で、サーバー側のレンダリングが必要です。また、いくつかの残りのAPIがあり、すべてのAPI(登録用のもの)の前に1つのAPIを呼び出す必要があります。私は初期状態のために、これをサーバー上のAPI(登録用データを必要とする最初のAPI)と呼び、レスポンスデータをストアに保存してクライアントにストアを返す必要があると思います。定義された初期店舗作りのためにもサーバー側redux-saga初期状態

/** 
* Create the store with asynchronously loaded reducers 
*/ 

import { createStore, applyMiddleware, compose } from 'redux'; 
import { fromJS } from 'immutable'; 
import { routerMiddleware } from 'react-router-redux'; 
import createSagaMiddleware from 'redux-saga'; 
import createReducer from './reducers'; 

const sagaMiddleware = createSagaMiddleware(); 

export default function configureStore(initialState = {}, history) { 
    // Create the store with two middlewares 
    // 1. sagaMiddleware: Makes redux-sagas work 
    // 2. routerMiddleware: Syncs the location/URL path to the state 
    const middlewares = [ 
    sagaMiddleware, 
    routerMiddleware(history), 
    ]; 

    const enhancers = [ 
    applyMiddleware(...middlewares), 
    ]; 

    // If Redux DevTools Extension is installed use it, otherwise use Redux compose 
    /* eslint-disable no-underscore-dangle */ 
    const composeEnhancers = 
    process.env.NODE_ENV !== 'production' && 
    typeof window === 'object' && 
    window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? 
     window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ : compose; 
    /* eslint-enable */ 

    const store = createStore(
    createReducer(), 
    fromJS(initialState), 
    composeEnhancers(...enhancers) 
); 

    // Extensions 
    store.runSaga = sagaMiddleware.run; 
    store.asyncReducers = {}; // Async reducer registry 

    // Make reducers hot reloadable, see http://mxs.is/googmo 
    /* istanbul ignore next */ 
    if (module.hot) { 
    module.hot.accept('./reducers',() => { 
     import('./reducers').then((reducerModule) => { 
     const createReducers = reducerModule.default; 
     const nextReducers = createReducers(store.asyncReducers); 

     store.replaceReducer(nextReducers); 
     }); 
    }); 
    } 

    return store; 
} 

と::反応-定型でストアを作成するために、その後

async function fetches (hostname) { 
    const domain = hostname.replace('.myExample.com', '').replace('www.', ''); 
    const options = { 
    method: 'GET', 
    headers: { 
     'Content-Type': 'application/x-www-form-urlencoded', 
     'Accept': 'application/example.api.v1.0+json', 
    } 
    }; 
    const uri ='https://api.example.com/x/' + domain + '/details'; 
    const shopDetail = await fetch(uri, options); 
    return shopDetail.json(); 
} 

function renderAppToStringAtLocation(hostname ,url, { webpackDllNames = [], assets, lang }, callback) { 
    const memHistory = createMemoryHistory(url); 
    console.log('url :', hostname); 
    fetches(hostname).then(data => { 
    const store = createStore(data, memHistory); 

    syncHistoryWithStore(memHistory, store); 

    const routes = createRoutes(store); 

    const sagasDone = monitorSagas(store); 

    store.dispatch(changeLocale(lang)); 

    match({ routes, location: url }, (error, redirectLocation, renderProps) => { 
     if (error) { 
    callback({ error }); 
     } else if (redirectLocation) { 
    callback({ redirectLocation: redirectLocation.pathname + redirectLocation.search }); 
     } else if (renderProps) { 
    renderHtmlDocument({ store, renderProps, sagasDone, assets, webpackDllNames }) 
     .then((html) => { 
     const notFound = is404(renderProps.routes); 
     callback({ html, notFound }); 
     }) 
     .catch((e) => callback({ error: e })); 
     } else { 
    callback({ error: new Error('Unknown error') }); 
     } 
    }); 
    }); 

と:

function renderAppToStringAtLocation(url, { webpackDllNames = [], assets, lang }, callback) { 
    const memHistory = createMemoryHistory(url); 
    const store = createStore({}, memHistory); 

    syncHistoryWithStore(memHistory, store); 

    const routes = createRoutes(store); 

    const sagasDone = monitorSagas(store); 

    store.dispatch(changeLocale(lang)); 

    match({ routes, location: url }, (error, redirectLocation, renderProps) => { 
    if (error) { 
     callback({ error }); 
    } else if (redirectLocation) { 
     callback({ redirectLocation: redirectLocation.pathname + redirectLocation.search }); 
    } else if (renderProps) { 
     renderHtmlDocument({ store, renderProps, sagasDone, assets, webpackDllNames }) 
    .then((html) => { 
     const notFound = is404(renderProps.routes); 
     callback({ html, notFound }); 
    }) 
    .catch((e) => callback({ error: e })); 
    } else { 
     callback({ error: new Error('Unknown error') }); 
    } 
    }); 
} 

を初期状態に充填するため、私はいくつかの変更を行いますコンソールでこのエラーが表示されます:

Unexpected properties "code", "data" found in initialState argument 
passed to createStore. Expected to find one of the known reducer 
property names instead: "route", "global", "language". Unexpected 
properties will be ignored. 

どのようにそれを修正するには?

答えて

0

I thinks for initial state I need to call this (first API that need data for registration) API on the server and save response data into store and return store to client

APIコールを実行する側に依存する2つのソリューションがあります。

サーバー側の呼び出しの場合は、fetchが実行されるまで、HTTP応答とその後のSSRフェーズが遅延される必要があります。ミドルウェア機能にラッピングすることでexpressに解決できます。通常、このようなスキーマは外部認証サービス(Auth0、Passportなど)と統合するときに使用されますが、認証情報をではなくJWTにラップする方がよいでしょう。

クライアント側からAPI呼び出しができる場合は、redux-sagaを使用してください。それはAPIコールが完了する前にすべてのレビュックスアクションをキャッチし、それぞれそれを再生する専用のプロセスを生成することができます。この場合、initialStateオブジェクトには、データのない構造体のようなフィールドが含まれている必要があります。このフィールドは、APIコールの後で埋められます。

関連する問題