Reaction-router-redux: Невозможно обновить представление / страницу после отправки действия замены для сохранения (с обновленным хранилищем url и redux) - PullRequest
0 голосов
/ 20 июня 2019

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

URL-адрес обновлен, и действие LOCATION_CHANGE успешно отправлено, но представление / страница не обновляется.

CodeSandBox: https://codesandbox.io/s/elegant-cdn-sm6zg

import React, { Component } from "react";
import ReactDOM from "react-dom";
import "./App.css";
import A from "./components/A";
import B from "./components/B";
import BFallback from "./components/BFallback";
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Redirect
} from "react-router-dom";
import createHistory from "history/createBrowserHistory";
import { Provider } from "react-redux";
import { applyMiddleware, createStore, compose } from "redux";
import rootReducer from "./reducers/rootReducer";
import {
  routerMiddleware,
  replace,
  syncHistoryWithStore
} from "react-router-redux";
import { Prompt } from "react-router";
import Nav from "./components/Nav";

let history = createHistory();
const middleware = routerMiddleware(history);
const store = createStore(rootReducer, applyMiddleware(middleware));
history = syncHistoryWithStore(history, store);

const PrivateRoute = ({
  component: Component,
  forward,
  fallbackPath,
  ...rest
}) => (
  <Route
    {...rest}
    render={props => {
      console.log("forward:::::", forward);
      return forward ? (
        <Component {...props} />
      ) : (
        <Redirect
          to={{
            pathname: fallbackPath,
            state: { from: props.location }
          }}
        />
      );
    }}
  />
);

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      loggedIn: false,
      showCustomModal: false,
      nextLocation: null
    };
  }
  setLoggedIn = loggedIn => {
    this.setState({ loggedIn });
  };
  handleBlockedNavigation = nextLocation => {
    this.setState({
      nextLocation
    });
    return false;
  };
  forwardNavigation = () => {
    console.log("forwardNavigation:::::", this.state.nextLocation);

    //  changes redus state and url, but not view/page
    store.dispatch(replace(this.state.nextLocation.pathname));

    this.clearNextLocation();
  };
  clearNextLocation = () => {
    this.setState({ nextLocation: null });
  };
  render() {
    return (
      <Provider store={store}>
        <Router basename={window.location.pathname} history={history}>
          <div>
            <Nav
              setLoggedIn={this.setLoggedIn}
              loggedIn={this.state.loggedIn}
            />
            <Prompt message={this.handleBlockedNavigation} />
            {this.state.nextLocation && (
              <div
                style={{
                  position: "absolute",
                  top: "50%",
                  left: "50%",
                  transform: "translate(-50%,-50%)",
                  boxShadow: "0 0 10px 1px rgba(0,0,0,0.2)",
                  padding: "15px"
                }}
              >
                Are you sure you want to leave?
                <button onClick={this.forwardNavigation}>Yes</button>
                <button onClick={this.clearNextLocation}>No</button>
              </div>
            )}
            <Switch>
              <Route exact path={`/A`} component={A} />
              <PrivateRoute
                exact
                path={`/B`}
                component={B}
                forward={this.state.loggedIn}
                fallbackPath="/BFallback"
              />
              <PrivateRoute
                exact
                path={`/BFallback`}
                component={BFallback}
                forward={!this.state.loggedIn}
                fallbackPath="/B"
              />
              <Route path={`/`} component={A} />
            </Switch>
          </div>
        </Router>
      </Provider>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Я ожидаю, что представление / страница, состояние приращения и URL-адрес изменятся одновременно. Любая помощь будет принята с благодарностью. Большое спасибо.

...