在React应用中点击返回按钮不会重新加载页面

时间:2019-07-08 23:18:40

标签: javascript reactjs react-router mobx mobx-react

我有一个使用TypeScript编写的React应用(16.8.6),该应用使用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观察位置的变化,那我该怎么办?

4 个答案:

答案 0 :(得分:1)

如果我没记错的话,使用浏览器后退功能不会重新加载页面(我可能错了)。

为什么不尝试通过浏览器检测后退动作,而是在检测到后重新加载页面?

单击浏览器后退按钮时,您可以尝试使用以下代码手动重新加载页面。

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

出于好奇,为什么您需要这么多不同的商店?

答案 1 :(得分:1)

我不知道您是否已经看过,但是这个答案可能会帮助您或至少让您了解如何做出反应来解决此问题。

this question

答案 2 :(得分:1)

您可以在组件中实现类似这样的内容:

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配合使用会更好。

答案 3 :(得分:0)

反应路由器监视url的更改并呈现为路由aka url定义的关联组件。 您必须手动刷新或调用窗口函数才能重新加载。