web-dev-qa-db-ja.com

React Reduxアプリでサーバーから初期データを取得するにはどうすればよいですか?

私はReact/Reduxを学び始め、おそらく非常に基本的な質問であることにつまずいた。以下は簡単にするためにいくつかのコードを削除した私のアプリの抜粋である。

私の状態は、デフォルトでは空のサイトの配列によって記述されます。後のリデューサーには、ユーザーが別のページにページを移動するたびに別のサイトのセットをロードする_LOAD_SITES_アクションがありますが、現時点では何もしていません。 Reactは、まずPublishedSitesPageをレンダリングし、次にPublishedSitesBoxをレンダリングします。その後、データをループ処理し、個々のサイトをレンダリングします。

私がやりたいのは、デフォルトの空の配列ですべてをレンダリングし、その間「サーバーからサイトをロード」プロミスを開始し、解決したら_LOAD_SITES_アクションをディスパッチすることです。この電話をかける最良の方法は何ですか?私はPublishedSitesBoxまたはおそらくcomponentDidMountのコンストラクターについて考えていました。しかし、これがうまくいくかどうかはわかりません-私の懸念は、再レンダリングを続けるこの方法で無限ループを作成することです。 「haveRequestedInitialData」の行に沿って他の状態パラメーターを持たせることで、何らかの方法でこの無限ループを防ぐことができると思います。もう1つのアイデアは、ReactDOM.render()を実行した直後にこの約束をすることです。これを行うための最良かつ最もクリーンな方法は何ですか?

_export default function sites(state = [], action) {
  switch (action.type) {
    default:
      return state;
  }
}
...

const publishedSitesPageReducer = combineReducers({
  sites
});

ReactDOM.render(
  <Provider store={createStore(publishedSitesPageReducer)}>
    <PublishedSitesPage />
  </Provider>,
  this.$view.find('.js-published-sites-result-target')[0]
);

...

export default function PublishedSitesPage() {
  return (
    <PublishedSitesBox/>
  );
}

...

function mapStateToProps(state) {
  return { sites: state.sites };
}

const PublishedSitesBox = connect(mapStateToProps)(({sites}) => {
  // render sites
});
_
47
Eugene

このデータロードロジックがReactコンポーネントにまったく触れない理由はありません。ここで必要なのは、リデューサーにアクションをディスパッチするためのプロミスを返すことです。ストア。これにより、Reactコンポーネントが適切に再レンダリングされます。

(ReactDOM.renderを呼び出す前または後に非同期呼び出しを開始するかどうかは関係ありません。約束はどちらの方法でも機能します)

このようなもの:

var store = createStore(publishedSitesPageReducer);

someAsyncCall().then(function(response) {
  store.dispatch(someActionCreator(response));
});

ReactDOM.render(
  <Provider store={store}>
    <PublishedSitesPage />
  </Provider>,
  this.$view.find('.js-published-sites-result-target')[0]
);

Reactコンポーネントはストアのコンシューマーですが、ストアの唯一のコンシューマーである必要があるというルールはありません。

40
S McCrohan