3

React を react-router および Reflux と共にデータストアとして使用していますが、ページの更新を許可するために永続性を処理する最善の方法がわかりません。

私のコンポーネントは Reflux.connect を使用してストアに接続しますが、ストアはバックエンドからデータを取得するため、コンポーネントが最初に初期化およびレンダリングされるときはまだ使用できません。

ユーザーが最初からアプリに入ると、このすべてのデータが順番に読み込まれ、必要なときに利用できるようになりますが、ルートをさらに下ってページの更新をトリガーすると、react は、そうでないデータに依存するコンポーネントをレンダリングしようとします。まだあります。

LocalStorage に常にデータのコピーを保持し、それを Reflux ストア getInitialState() から提供することでこれを解決し、すべてのコンポーネントがレンダリング前にデータを取得できるようにしました。

これが正しい方法なのだろうか。何らかの理由でローカル ストレージ データが消去されたり破損したりすると、コンポーネントが正しいデータにアクセスできないため、インターフェイスが空白になります。サブ構造とプロパティが存在せず、javascript エラーが発生します。面倒で信頼できない解決策のようです。

これを解決するためにどのようなパターンが使用されているか知りたいです。

------編集----- WiredPrairieのコメントに答えるには:

1) getInitialState でデータを使用してコンポーネントを初期化するのはなぜですか?

私のコンポーネントが Reflux.connect を使用する場合、ストアがデータを取得する必要があるため、最初のレンダリングではまだデータが状態にありません。私のビューは現在、未定義のデータでは適切に機能しません。getInitialState() で Reflux ストアからローカルに保存されたキャッシュを返すことにより、接続されているすべてのコンポーネントは、最初のレンダリング呼び出しの前にそのデータを取得します。

2) ページが更新される原因と、最初と同じようにデータをロードできないのはなぜですか?

これは主に、編集時にページを更新する livereload を回避するために構築しなければならなかった回避策ですが (後で react-hotloader の使用を検討しますが、まだオプションではありません)、ユーザーはネストされたビューのどこかにいるときに更新を押すこともできます。それは同じ効果があります。手動で更新すると、開始時にアプリに入っていません。

3) コンポーネントがストアの変更イベントに関連付けられている場合、コンポーネントが更新されないのはなぜですか?

それらは更新されますが、私が言ったように、彼らは現在空のデータを処理しておらず、最初のレンダリングで、ストアが何かを取得するのを待ってそれを見逃すでしょう. すべてのビューを空のデータで正常に動作させることはできますが、それでは多くのボイラープレート コードが追加されます。

これまでの回答から、私が localStorage で行っていることは一般的な方法であると感じています。localStorage や sessionStorage などにローカルにキャッシュし、更新直後にそのデータを提供します。

localStorage が適切に機能しないという奇妙な機会に空のデータを適切に処理することで、ビューをもう少し堅牢にする必要があります。

4

1 に答える 1

0

私は、emitChange() が起動したときに各 Store を sessionStorage にキャッシュし、キャッシュされたデータが存在する場合は sessionStorage からストアを初期化し、それ以外の場合は null 値を初期化しています。ビューが null 値を処理できる場合、これは機能するようです。これはおそらく良い考えです (これが主な問題のようです)。

ビューでデータがない場合を適切に処理し、キャッシュが利用できない場合はすべてを null 値で初期化し、データが返されるたびにバックエンドを呼び出してアクションで null 値を更新することをお勧めします。

私は Reflux を試していませんが、通常の Flux では次のようになります (同じ原理を適用できるかもしれません)。

var _data;

if (sessionStorage.PostStore)
  _data = JSON.parse(sessionStorage.PostStore);
else {
  _data = {
    posts: null
  };
  BackendAPI.getPosts(function(err, posts) {
    if (posts) {
      PostActions.setPosts(posts);
    }
  });
}

...

AppDispatcher.register(function(payload) {
  var action = payload.action;

  switch (action.actionType) {

    ...

    case Constants.SET_POSTS:
      _data.posts= action.data.posts;
      break;

    default: 
      return true
  }

  // Update cache because state changed
  sessionStorage.PostStore = JSON.stringify(_data);

  PostStore.emitChange();
  return true;
});
于 2015-02-13T19:43:50.527 に答える