【问题标题】:Hitting Back button in React app doesn't reload the page在 React 应用程序中点击返回按钮不会重新加载页面
【发布时间】:2019-11-18 11:31:31
【问题描述】:

我有一个用 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 观察位置的变化,我该怎么做?

【问题讨论】:

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


【解决方案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 一起使用。

【讨论】:

  • 我喜欢这个想法,它似乎是一种直接观察位置属性并采取相应行动的方法。我对 mobx-state-router 不熟悉,但我也会检查一下。
【解决方案2】:

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

为什么不尝试检测浏览器的返回操作并在检测到时重新加载页面?

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

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

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

【讨论】:

  • 我为每个页面设置了一个商店,这似乎是一种分离不同数据集的合乎逻辑的方式。
  • 我明白了.. 我只是好奇。哈哈
【解决方案3】:

React 路由器监控 url 变化并渲染为路由 aka url 定义的关联组件。 您必须手动刷新或调用窗口函数才能重新加载。

【讨论】:

    【解决方案4】:

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

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

    【讨论】:

      猜你喜欢
      • 2012-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-04
      • 2021-11-15
      • 2023-03-27
      • 1970-01-01
      相关资源
      最近更新 更多