2017-02-14 6 views
0

私はreact-redux + thunk + redialを使用し、サーバー側でHTMLを生成します。私は反応ヘルメットによって別のサーバから来るユーザデータを使ってメタタグを生成したい。私のサーバーで :APIから呼び出されたデータを使用してサーバー側のレンダリングを行います

import { trigger } from 'redial'; 
trigger('fetch', components, locals) 
     .then(() => { 
      const state = getState(); 
      var html = ReactDOMServer.renderToString (
       <Provider store={store} key="provider"> 
        <ReactRouter.RouterContext {...renderProps} /> 
       </Provider> 
     ); 
let head = Helmet.rewind(); 
response.send(`<!DOCTYPE html> 
       <head> 
       <meta charSet="UTF-8"></meta> 
       <meta httpEquiv="X-UA-Compatible" content="IE=edge,chrome=1"></meta> 
       <meta name="viewport" content="width=device-width, initial-scale=1"></meta> 
       <link rel='stylesheet' href='/css/bootstrap.css'/> 
       ${style? "<style>"+style+"</style>" : "<link rel='stylesheet' href='/css/app.css'/>"} 
        ${head.title} 
        ${head.meta} 
        ${head.link} 
        ${head.script} 
       </head> 
       <body> 
        <div id="app">${html}</div> 
        <script src='/javascript/bundle.js'></script> 
        ${popUp} 
       </body> 
       </html>`); 

私のコンポーネントでは、私はAPIを呼び出して、ユーザーデータを返すアクションファイル内の関数を実行するために、レンダリング()関数での発送を呼び出します。私がどこでディスパッチを使用しても、それは同じ結果を持っています。最良の状態では、Reactは要求を返し、他のサーバーからのデータを待ちます。しかし、サーバーから受信したデータをチェックするように設定したため、何も返されません。

マイコンポーネント

var profile=[], shouldRender = false 
export var Profile = React.createClass({ 
render() { 
    var {x,y,z} = this.props; 
    var pathArray = (this.props.path).split('/'); 
    if(!canUseDOM && shouldRender == false)dispatch(
    actions.theProfile(x,y,z) 
).then((es) => {profile = es; shouldRender= true;Promise.resolve()}) 
    .catch((et) => console.log("error")); 

if(shouldRender){ 
    console.log("got inside"); 
    return (
    <div className="container"> 
     <RightSideBar page="profile"/> 
     <Helmet 
      title={metaData('title', name, profileId)}/> 
     <div className="col-md-6 col-xs-12 col-md-offset-3 content right"> 
     <div className="row"> 
      {profileContent(ideaTypes)} 
     </div> 
     </div> 
     <div className="col-md-3 col-xs-12 sidebar-left hidden-xs hidden-sm hidden-md"> 
     <LeftSideBar page="profile"/> 
     </div> 
    </div> 
) 
} 
}); 

および方法は不変であるために仮定されてレンダリングするのでrender()方法での発送を呼び出すaxios

export var viewingProfile = (ux,y,z) => { 
    return function (dispatch, getState) { 
     return axios.post(root + '/api/getUser', { 
      Id: x, 
      orgid: y, 
      profileId: z 
     }) 
     .then(function (res) { 
     if(res.data.statusEntity.statusCode == -201){ 
      window.location.href = "/user-not-found" 
     } else { 
      dispatch(updateState(res.data)) 
      return res.data; 

     } 
     }) 
    } 
    } 

答えて

0

最後に、別のサーバーからのデータをレンダリングして、サーバー側のレンダリングに反応させた後、私は最適なソリューションを見つけました。 まず、リダイヤルは必要ありません。それは少なくとも私の場合は冗長です。だから私はそれを私のソースから削除しました。 そして、私は移動私のルート

export default (store) => { 
const requireApiCall= (nextState, replace, cb) => { 
    var state = store.getState(); 
    return store.dispatch(actions.theProfile(x,y,z)). 
    then(()=>{ 
     cb() 
    }) 

}; 
<Route path="/" component={App}> 
    <IndexRoute component={Home}/> 
    <Route path="profile" component={Profile } onEnter={requireApiCall}> 
    </Route> 
</Route> 
} 

発送が実行され、ルートがコールバック「CB()」と、私のAPIコールが応答されたとき、私の店は、更新を取得するのを待つに

dispatch(
actions.theProfile(x,y,z) 
) 

受け取ったデータと比較する。次に、actionはpromiseを解決し、次にrequireApiCallの中の約束を解決して、コールバック "cb()"を返します。ルートはコンポーネントのレンダリングを開始し、クライアントに送信されるアンサーは受信したデータを使用して生成されます。

私はそれが少し複雑ですが、完全に動作することを知っています。

0

を使用してAPIを呼び出して、私の行動は、間違ったやり方です。データapiを解決するにはredialによって提供されるフックでコンポーネントをラップします。 redial repoの使用例を参照してください。

+0

私はそれを行う必要があります、私はこの質問を書いた後に気づいたが、私はそれをテストしていない。私は明日それをやるつもりです。私はそれが問題を解決することを願っています – alireza

+0

私はそれをしましたが、問題は残っています。それは行動を呼んでいない。 – alireza

関連する問題