web-dev-qa-db-ja.com

Reactアプリで[戻る]ボタンを押すと、ページが再読み込みされません

Reactアプリ(16.8.6)がTypeScriptで記述されており、React Router(5.0.1)とMobX(5.9.4)を使用しています。正常に機能し、必要なときにデータが読み込まれますが、ブラウザの[戻る]ボタンをクリックすると、URLは変更されますが、状態は更新されず、ページは再レンダリングされません。この問題とwithRouterに関する記事を無限に読みました私が試した修正ですが、違いはありません。

典型的な使用例は、概要ページに移動し、新しいデータをロードして新しい履歴状態をプッシュするさまざまなものを選択してから、いくつかの手順を開始した場所に戻します。ほとんどの履歴プッシュは、いくつかのルートを処理するサマリーコンポーネント内で発生します。サマリーページからホームページに戻ると、再レンダリングが必要に応じて行われることに気づきました。

私のindex.tsx

import { Provider } from 'mobx-react'
import * as React from 'react'
import * as ReactDOM from 'react-dom'

import App from './App'
import * as serviceWorker from './serviceWorker'
import * as Utils from './utils/Utils'

const rootStore = Utils.createStores()

ReactDOM.render(
    <Provider {...rootStore }>
        <App />
    </Provider>,
    document.getElementById('root') as HTMLElement
)

serviceWorker.unregister()

私のapp.tsx

import * as React from 'react'
import { inject, observer } from 'mobx-react'
import { Route, Router, Switch } from 'react-router'

import Home from './pages/Home/Home'
import PackageSummary from './pages/PackageSummary/PackageSummary'
import ErrorPage from './pages/ErrorPage/ErrorPage'
import { STORE_ROUTER } from './constants/Constants'
import { RouterStore } from './stores/RouterStore'

@inject(STORE_ROUTER)
@observer
class App extends React.Component {
    private routerStore = this.props[STORE_ROUTER] as RouterStore

    public render() {
        return (
            <Router history={this.routerStore.history}>
                <Switch>
                    <Route exact path="/" component={Home} />
                    <Route exact path="/summary/:packageId" component={PackageSummary} />
                    <Route exact path="/summary/:packageId/:menuName" component={PackageSummary} />
                    <Route exact path="/summary/:packageId/:menuName/:appName" component={PackageSummary} />
                    <Route component={ErrorPage} />
                </Switch>
            </Router>
        )
    }
}

export default App

私のルーターストア

import { RouterStore as BaseRouterStore, syncHistoryWithStore } from 'mobx-react-router'
import { createBrowserHistory } from 'history'

export class RouterStore extends BaseRouterStore {
    constructor() {
        super()
        this.history = syncHistoryWithStore(createBrowserHistory(), this)
    }
}

MobXストアの作成方法

export const createStores = () => {
    const routerStore = new RouterStore()
    const packageListStore = new PackageListStore()
    const packageSummaryStore = new PackageSummaryStore()
    const packageUploadStore = new PackageUploadStore()

    return {
        [STORE_ROUTER]: routerStore,
        [STORE_SUPPORT_PACKAGE_LIST]: packageListStore,
        [STORE_SUPPORT_PACKAGE_SUMMARY]: packageSummaryStore,
        [STORE_SUPPORT_PACKAGE_UPLOAD]: packageUploadStore
    }
}

だから私の質問は:

  1. ユーザーがブラウザを介して戻る/進むときに、ページに適切なデータをロードするにはどうすればよいですか?
  2. ソリューションがMobXに場所の変更を監視させることができる場合、どうすればよいですか?
10
Chris Tybur

コンポーネントに次のようなものを実装できます。

import { inject, observer } from 'mobx-react';
import { observe } from 'mobx';

@inject('routerStore')
@observer
class PackageSummary extends React.Component {
  listener = null;
  componentDidMount() {
    this.listener = observe(this.props.routerStore, 'location', ({ oldValue, newValue }) => {
      if (!oldValue || oldValue.pathname !== newValue.pathname) {
        // your logic
      }
    }, true)
  }

  componentWillUnmount() {
    this.listener();
  }
}

このアプローチの問題は、/summaryから他のページ('/'など)に戻るとコールバックが開始されるため、これがどのルートであるかを確認する必要があることです。これらの種類の複雑さのために、私は mobx-state-router を使用することをお勧めします。これは、MobXで使用する方がはるかに良いことがわかりました。

2
zhuber

ReactルーターはURLの変更を監視し、ルート(別名URL)に定義された関連コンポーネントをレンダリングします。手動で更新するか、ウィンドウ関数を呼び出してリロードする必要があります。

1
att

あなたがすでにそれを見たことがあるかどうかはわかりませんが、この回答はおそらくあなたに役立つかもしれません。

https://stackoverflow.com/a/39363278/9208722

私の記憶が正しければ、ブラウザの戻る機能を使用してもページはリロードされません(私は間違っているかもしれません)。

ブラウザで戻るアクションを検出し、代わりに検出されたときにページをリロードしてみませんか?

次のコードを試して、ブラウザの戻るボタンがクリックされたときにページを手動でリロードできます。

$(window).bind("pageshow", function() {
  // Run reload code here.
});

また、好奇心から、なぜそれほど多くの異なる店舗が必要なのですか?

1
Norman