如何访问组件外部的历史记录对象(使用HashRouter)?

时间:2020-04-16 19:41:54

标签: reactjs react-router

我在这里阅读了react-router文档:https://github.com/ReactTraining/react-router/blob/master/FAQ.md#how-do-i-access-the-history-object-outside-of-components

本文使用路由器解决了该解决方案;但是,我需要在实现中使用HashRouter(针对每个业务案例)。有什么办法可以做到这一点?

1 个答案:

答案 0 :(得分:0)

在实现存储某些页面历史记录之前,我已经完成了此操作。您需要在反应dom渲染期间执行此操作。

我只是直接向历史对象本身添加了功能。我没有使用HashRouter的经验,但这是我对BrowserRouter所做的事情。您甚至可以将redux存储传递给createHistory函数或您可能需要的任何“业务”服务的实例。或者甚至可以将历史实例本身传递给您的业务服务。

示例:

import React from "react";

import { Provider } from "react-redux";
import ReactDOM from "react-dom";

import { createBrowserHistory } from "history";
import { Router, matchPath } from "react-router-dom";

import App from "./App";

// Function that handles creation of our redux store
import createStore from "./store";

// Function that handles creation of our custom history
// Would normally outsource this to its own file to be imported
const getFullURL = (location) => location.pathname + location.search;
export default (limit = 25) => {
  const history = createBrowserHistory();

  // Extend our history with a stack
  history.stack = [getFullURL(history.location)];

  // Add ability to listen to our history
  history.listen((location, action) => {
    const url = getFullURL(location);

    if (action === "REPLACE") {
      history.stack.pop();
    }

    history.stack.push(url);

    if (history.stack.length > limit) {
      history.stack.shift();
    }
  });

  // Extend our history with a function to go back to the
  //  most recent match route
  history.goToMostRecent = (routes, defaultPath = false) => {
    for (let i = history.stack.length - 1; i > -1; i--) {
      const path = history.stack[i];
      const strippedPath = path.split("?")[0];
      for (let j = 0; j < routes.length; j++) {
        const route = routes[j];
        const match = matchPath(strippedPath, {
          exact: true,
          path: route,
        });

        if (match) {
          history.push(path);
          return;
        }
      }
    }

    if (defaultPath) history.push(defaultPath);
  };

  return history;
};

const store = createStore();

// custom history with stack + extra actions
// could even pass in our store if we needed to access it for some reason
const history = createHistory();

ReactDOM.render(
  <Provider store={store}>
    <Router history={history}>
      <App />
    </Router>
  </Provider>,
  document.getElementById("root")
);