2016-09-11 31 views
1

私はReact、React-router、Redux、ImmutableでUniversal/Isomorphicアプリを構築しようとしています。私は、サーバーのレンダリングを行い、HTMLとともにクライアントに初期状態を返すように管理しました。しかし、クライアントは、その初期状態でレンダリングしていないようです。 クライアントは初期状態でレンダリングしません

私のサーバーコード:

1.Handleルート:

import {match,RouterContext,Router,Route,browserHistory} from "react-router"; 
import {Provider} from "react-redux"; 
import {createStore} from "redux"; 
import {createRouter} from "../../shared/support/routers"; 
import reducer from "../../shared/reducer"; 
import ReactDOMServer from "react-dom/server"; 
import React from "react"; 
import Immutable from "immutable"; 
import {RenderPage} from "../routes/helper"; 

function homeRender(req, res) { 

    match({routes, location: req.url}, (err, redirectLocation, renderProps)=> { 
     if (redirectLocation) { 
      //@TODO: response redirect location 
      console.log('redirect location'); 
     } 
     if (err) { 
      //@TODO: response error 
      console.log(err.stack); 
     } 
     if (!renderProps) { 
      //@TODO: route to 404 
      console.log("no renderProps"); 
     } 

     Article.getArtilceByPage(1,20) 
      .then(questions=>{ 
       let state = Immutable.fromJS({ 
        title:"Home page render on server side", 
        qs:questions 
       }); 
       let store = createStore(reducer,state); 
       store.dispatch({ 
        type: "SET_STATE", 
        state: state 
       }); 
       let html = ReactDOMServer.renderToString(
        <Provider store={store}> 
         <RouterContext {...renderProps}/> 
        </Provider> 
       ); 
       let fullPage = RenderPage(html, store.getState()); 
       res.end(fullPage); 
      }) 
     .catch(function(e) { 
      res.end(e); 
     }); 

    }); 
} 

2.ページのコードをレンダリング:window.__PRELOADED_STATE__はレスポンスのHTMLにレンダリングされる

export function RenderPage(content,state) { 
    let temp = `<!DOCTYPE html> 
<html> 
    <head> 
    <meta charset="UTF-8"> 
    <title>${state.get('title')}</title> 
    <meta name='og:title' content='Dont ask me for it'/> 
    <script> 
      window.__PRELOADED_STATE__ = ${JSON.stringify(state)} 
    </script> 
    </head> 
    <body> 
    <div id='app'><div>${content}</div></div> 
    <script type="text/javascript" src="manifest.js"></script> 
    <script type="text/javascript" src="vendor.js"></script> 
    <script type="text/javascript" src="app.js"></script> 



    </body> 
    </html>`; 
    return temp; 
} 

減速コード:

import {Map} from "immutable"; 
export default function (state = Map(), action) { 
    switch (action.type) { 
     case "SET_STATE": 
      return setState(state,action.state); 
     case "HANDLE_CLICK": 
      handleClick(); 
      //console.log("Hello there"); 
    } 
} 
//initial state 
function setState(state,newState) { 
    return state.merge(newState); 
} 
//handle user click 
function handleClick(state,action) { 

    console.log("This one could not be pass child comps"); 

} 
import {Router,Route} from "react-router"; 
import React from "react"; 
import App from "../components/app"; 
import {HomeContainer} from "../components/home"; 
import {TagContainer} from "../components/tag"; 

export function createRouter(hist) { 
    const routes = <Route component={App}> 
     <Route path="/" component={HomeContainer}/> 
     <Route path="tag" name="tag" component={TagContainer}/> 
    </Route>; 
    return (
     <Router history={hist}>{routes}</Router> 
    ); 
} 

、最終的には:クライアントコード:

import React from "react"; 
import ReactDOM from "react-dom"; 
import {Router,Route,browserHistory } from "react-router"; 
import {Provider} from "react-redux"; 
import {createStore} from "redux"; 
import reducer from "./reducer"; 
import Immutable from "immutable"; 
import {createRouter} from "./support/routers"; 

console.log(windows.__PRELOADED_STATE__); 
const state = Immutable.fromJS(window.__PRELOADED_STATE__); 
const store = createStore(reducer,state); 
const routes = createRouter(browserHistory); 


store.dispatch({ 
    type: "SET_STATE", 
    state: state 
}); 
    ReactDOM.render(
     <Provider store={store}> 
      {routes} 
     </Provider> 
     , document.getElementById("app")); 

結果:は、クライアントとサーバーの両方でルートを作成するためのコードを共有し、クライアントがサーバーによってレンダリングされたHTMLを表示することができます。ウィンドウからの初期のストア/ステートはできません。 PRELOADED_STATE。 私は、index.jsファイルのコードがまったく実行されていなかったと思います。

更新日:減速で "HANDLE_CLICK" を扱うしようとしたときにエラーを引き起こすコード: home.js

import React from "react"; 
import PureRenderMixin from 'react-addons-pure-render-mixin'; 
import {connect} from "react-redux"; 
import * as actionCreator from "./support/action_creator"; 
import HomeList from "./subComponents/homelist"; 

export class HomeComp extends React.Component { 
    constructor(props) { 
     super(props); 
     this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this); 
    } 

    getQuestions() { 
     return this.props.data.questions || []; 
    } 

    render() { 
     //console.log(this.getQuestions()); 
     //console.log(this.props.questions); 
     //console.log(this.props); 
     return <div className="home"> 
      <h1>kkk</h1> 
      <smal>Here is a list for home stuff</smal> 
      <HomeList {...this.props}/> 
     </div> 
    } 
} 
//<HomeList {...this.props}/> 
function mapStateToProps(state) { 
    return { 
     questions: state.get('qs') // this cause error in console devTool 
    }; 
} 
export const HomeContainer = connect(mapStateToProps, actionCreator)(HomeComp); 

enter image description here

+0

なぜ 'createStore'の後に' 'SET_STATE''をディスパッチしていますか? – DDS

+0

ありがとうございます。クライアントコードとサーバーコードの両方でディスパッチを削除しました。まだ動かない。何か案が? –

答えて

0

あなたがwindowsのオフにそれをつかんでいるあなたはconsole.log状態を存在しないと投げるべきである。

スローがコードフローを破るので、renderコールには到達しません。

問題をデバッグするには、常にDevToolsを使用する必要があります。コードブラインドは非常に難しいです。なぜあなたのアプリが純粋にそれが生成する出力に基づいて動作していないかを知ることは非常に難しいです。

デバッグツールを使用すると、変数の検査、ブレークポイントの設定、およびアドホックコードの評価を行うことができます。それは本当に不可欠です。

+0

私はレデューサーのボタンコールHANDLE_CLICKをクリックしようとしています。ここでdevtoolコンソールがあります: "connect.js:323 Uncaught TypeError:プロパティ '未定義のget'を読み取ることができません。コード原因エラーは次のとおりです。 'code'function mapStateToProps(state){ return { questions:state.get( 'qs') }; } エクスポートconst HomeContainer =接続(mapStateToProps、actionCreator)(HomeComp); 。 home.jsのコード行の更新された質問を参照してください –

+0

'console.log(windows .__ PRELOADED_STATE __);'行は 'windows'が定義されていないため投げられます。上記のコードは正確にコピーペーストされていないか、クライアントにストアがありません。あなたのクライアントが 'mapStateToProps'に到達しているようだが、あなたのコードが最新ではないようだ。 – DDS

+0

console.log行を削除しましたが、依然としてクライアント側にストアを作成できません。ウィンドウからクライアントへのストアを作成する方法.__ PRELOADED_STATE__ ?? –

関連する問題