web-dev-qa-db-ja.com

Reactルータ、ブラウザの戻るボタンの後に状態を復元する方法は?

React SPAアプリがユーザーが戻る/進むブラウザボタンでナビゲートするときに状態を維持する方法を見つけようとしています。たとえば、ユーザーがフォームに入力してから、転送すると、フォームは自動的に復元されます。

私は多くのJavaScriptルーターをレビューしましたが、この問題に適切に対処しているものはないようです...(またはまったく)。

現在、React Router 4を使用しています。これは、私が採用しているパターンです。

  1. プログラムでページを離れるとき、最初にhistory.replace(this.state);で現在のページの状態を保存します。 history.Push(newLocation)を使用してページから移動します
  2. ページコンポーネントが作成されたとき(componentWillMount)_this.props.location.state !== undefined_をチェックし、そうであれば、this.setState(this.props.location.state)で復元します

私の質問は、上記のパターンは正しいですか?提案?より良い、広く採用されている方法はありますか?

13
nino.porcino

しばらくして、私は合理的な回避策を見つけました:

  • this.setState()を使用するごとに、window.history.replaceState({ key: history.location.key, state: this.state})を使用して状態を履歴と同期させます
  • 「ページ」コンポーネントがマウントまたは更新されたとき(willMountおよびwillReceiveProps)_props.params.location.state_の状態を確認します。1つある場合は復元します。ない場合は、新しい状態を作成します。
  • 同じページでナビゲートするとき、ルートを使用せず、単に_this.setState_と_window.history.pushState_を使用します
  • ページの外に移動するとき、私はルートを使用し、状態で何かを渡すことを避けます

この解決策はうまく機能しているようで、マイナーな欠点は次のとおりです

  • 状態はシリアル化可能でなければなりません
  • _this.setState_は非同期であるため落とし穴です。後から_this.state_を使用することはできません。
  • 初期の空の状態は、復元または初期化フェーズ中に使用される関数によって提供される必要があり、Componentconstructor()に留まることはできません
  • firefoxでは、戻るボタンの後の自動スクロール復元はランダムに機能します。理由はわかりませんが、ChromeとEdgeは大丈夫です。

全体的に、すべての初期化/復元作業を行うPageComponentを拡張するComponentを作成しました。また、_this.setState_をオーバーライドして、履歴と自動的に同期させ、非同期の煩わしさを回避します。

10
nino.porcino