6

React/Redux アプリで初めてサーバー側のレンダリングを試みています。私が今抱えている問題は、初期状態でランダムに生成された文字列を作成し、それを小道具としてメインAppコンポーネントに渡す必要があることです。クライアントとサーバーに異なる文字列を生成しているため、これは明らかに問題を引き起こしています。この問題の発生を防ぐためにできることはありますか?

理解に役立つ基本構造:

App.js

import React from 'react';
import { connect } from 'react-redux';

const App = ({ randomStr }) => (
  <div> 
    <p>{randomStr}</p>
  </div>
);

const mapStateToProps = (state) => ({
  ...
});

const mapDispatchToProp = (dispatch) => ({
  ...
});

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(App);

そして私のレデューサー:

reducer.js

import { generateString } from '../util';
import { NEW_STRING } from '../constants';

const stringReducer = (state = generateString(), action) => {
  switch (action.type) {
    case NEW_STRING:
      return generateString();

    default:
      return state;
  }
};

export default stringReducer;

ご覧のとおりrandomStr、redux ストアから を取得してレンダリングしていますが、クライアントとサーバーでは異なります。どんな助けでも大歓迎です!

4

1 に答える 1

5

サーバー側でストアと初期状態を生成している場合、クライアントは同じことをしてデータの再生成を試みるべきではありません。

ストアと初期状態を (サーバー上で) 1 回だけ生成し、それをクライアントに渡す必要があります。そのためには、レンダリングする最初のコンポーネントにそれを注入する必要があります。

最も一般的な方法は、<script>タグを追加して状態をウィンドウにアタッチすることです。たとえば、window.__initialState.

たとえばReactDOM.renderToString、サーバー側で を使用して という初期コンポーネントをレンダリングするHtml場合、次のことができます。

const html = ReactDOM.renderToString(<Html initialState={initialState} />);

次に、Htmlコンポーネントにこのデータを挿入して、クライアントが後で使用できるようにします。

<script dangerouslySetInnerHTML={{ __html: `window.__initialState=${JSON.stringify(this.props.initialState)};` }}/>

その後、クライアント側で を使用window.__initialStateしてデータを取り戻すことができ、サーバーとクライアントで同じデータが得られます。

于 2016-07-24T08:59:08.997 に答える