Нажатие кнопки «Назад» в приложении 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 отслеживать изменения местоположения, как мне это сделать?

person Chris Tybur    schedule 08.07.2019    source источник
comment
Может быть, это будет полезно: stackoverflow.com/questions/4570093/   -  person The Witness    schedule 19.07.2019


Ответы (4)


Если я правильно помню, использование функции возврата в браузере не приводит к перезагрузке страницы (возможно, я ошибаюсь).

Почему бы не попытаться обнаружить обратное действие браузера и вместо этого перезагрузить страницу при обнаружении?

Вы можете попробовать следующий код, чтобы вручную перезагрузить страницу при нажатии кнопки возврата в браузере.

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

Также из любопытства, зачем вам столько разных магазинов?

person Norman    schedule 19.07.2019
comment
Я создал одно хранилище для каждой страницы, это казалось логичным способом разделения разных наборов данных. - person Chris Tybur; 25.07.2019
comment
Понятно ... Мне просто любопытно. Ха-ха - person Norman; 25.07.2019

Маршрутизатор React отслеживает изменения URL-адресов и отображает связанный компонент, определенный для маршрута, также известного как URL-адрес. Вам необходимо вручную обновить или вызвать функцию окна для перезагрузки.

person att    schedule 19.07.2019

Я не знаю, видели ли вы это уже, но этот ответ может помочь вам или, по крайней мере, дать вам представление о том, как реагировать на эти проблемы.

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

person Javier Pérez Batista    schedule 19.07.2019

Вы можете реализовать в своем компоненте что-то вроде этого:

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.

person zhuber    schedule 19.07.2019
comment
Мне нравится эта идея, кажется, это способ непосредственно наблюдать за свойством местоположения и действовать соответственно. Я не знаком с mobx-state-router, но я тоже это проверю. - person Chris Tybur; 25.07.2019