reactjs 如何用react-router在浏览器中停止/#/?

sq1bmfud  于 2022-11-22  发布在  React
关注(0)|答案(6)|浏览(133)

当使用react-router时,有什么方法可以防止/#/显示在浏览器的地址栏中吗?这是用ReactJS实现的。也就是说,点击链接转到一个新的路由时,会显示localhost:3000/#/localhost:3000/#/about。这取决于路由。

irlmq6kh

irlmq6kh1#

随着React Router一次又一次地被重构,这个问题的答案已经发生了巨大的变化。

版本6

其思想是将路由器设置为“浏览器路由器”,使用createBrowserRouter()函数创建该路由器,然后将其添加到React应用的根元素中。

import React from "react";
import ReactDOM from "react-dom/client";
import {
  createBrowserRouter,
  RouterProvider,
  Route,
} from "react-router-dom";

const router = createBrowserRouter([
  {
    path: "/",
    element: ...,
  },
]);

ReactDOM.createRoot(document.getElementById("root")).render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>
);

来源react-router Version 6 Docs: createBrowserRouter

版本4

对于react-router的版本4,语法非常不同,需要使用BrowserRouter作为路由器根标记。

import BrowserRouter from 'react-router/BrowserRouter'
ReactDOM.render (( 
  <BrowserRouter>
   ...
 <BrowserRouter> 
), document.body);

请注意,这将在版本6中工作,但不建议这样做,并且BrowserRouter组件不支持新的React Router数据API。
来源React Router Version 4 Docs

版本2和3

对于React Router的版本1、2和3,设置路由到URLMap方案的正确方法是将历史实现传递到<Router>history参数中。
简而言之,历史记录知道如何监听浏览器的地址栏以查找更改,并将URL解析为位置对象,路由器可以使用该对象来匹配路由并呈现正确的组件集。
在React路由器2和3中,路由配置代码如下所示:

import { browserHistory } from 'react-router'
ReactDOM.render (( 
 <Router history={browserHistory} >
   ...
 </Router> 
), document.body);

版本1

在1.x版中,您将改为使用下列程式码:

import createBrowserHistory from 'history/lib/createBrowserHistory'
ReactDOM.render (( 
  <Router history={createBrowserHistory()} >
   ...
  </Router> 
), document.body);

来源:2.0版升级指南

q8l4jmvw

q8l4jmvw2#

Router.run(routes, Router.HistoryLocation, function (Handler) {
  React.render(<Handler/>, document.body);
});

对于当前的0.11及更高版本,您需要将Router.HistoryLocation添加到Router.run()<Routes>现在已被弃用。有关0.12.x HistoryLocation实现的信息,请参阅升级指南。

4jb9z9bj

4jb9z9bj3#

如果你不需要支持IE8,你可以使用浏览器历史和react-router将使用window.pushState而不是设置哈希。
具体操作方式取决于您使用的React Router版本:

*版本4:https://reacttraining.com/react-router/web/api/BrowserRouter

wlp8pajw

wlp8pajw4#

实际上,你可以使用.htaccess来完成这个任务。浏览器通常需要查询字符串分隔符?#来确定查询字符串的开始位置和目录路径的结束位置。我们想要的最终结果是www.mysite.com/dir。因此,我们需要在Web服务器搜索它认为我们需要的/dir的目录之前发现这个问题。因此,我们将一个.htaccess文件放在项目的根目录中。

# Setting up apache options
    AddDefaultCharset utf-8
    Options +FollowSymlinks -MultiViews -Indexes
    RewriteEngine on

    # Setting up apache options (Godaddy specific)
    #DirectoryIndex index.php
    #RewriteBase /

    # Defining the rewrite rules
    RewriteCond %{SCRIPT_FILENAME} !-d
    RewriteCond %{SCRIPT_FILENAME} !-f

    RewriteRule ^.*$ ./index.html

然后使用window.location.pathname获取查询参数
然后,如果你想的话,你可以避免使用React路线,如果你想的话,只需要操纵网址和浏览器历史记录。希望这能帮助一些人...

k2fxgqgv

k2fxgqgv5#

安装历史记录包

npm install history --save

下一次导入创建历史记录并使用历史记录中的基本名称

import { createHistory, useBasename } from 'history';
...
const history = useBasename(createHistory)({
  basename: '/root' 
});

如果您的应用程序URL为www.example.com/myApp,则/root应为/myApp。
将历史变量传递给路由器

render((
  <Router history={history}>
    ...
  </Router>
), document.getElementById('example'));

现在,对于所有的Link标签,在所有路径前面附加一个“/”。

<Link to="/somewhere">somewhere</Link>

该解决方案的灵感来自React-Router Example,不幸的是,没有正确地记录在他们的API中。

insrf1ej

insrf1ej6#

另一种处理哈希后显示内容的方法(如果不使用pushState!)是创建CustomLocation并在创建ReactRouter时加载它。
例如,如果你想让hashbang url(所以用#!)符合谷歌抓取规范,你可以创建一个HashbangLocation.js文件,主要复制原始的HashLocation,如:

'use strict';

var LocationActions = require('../../node_modules/react-router/lib/actions/LocationActions');
var History = require('../../node_modules/react-router/lib/History');

var _listeners = [];
var _isListening = false;
var _actionType;

function notifyChange(type) {
  if (type === LocationActions.PUSH) History.length += 1;

  var change = {
    path: HashbangLocation.getCurrentPath(),
    type: type
  };

  _listeners.forEach(function (listener) {
    listener.call(HashbangLocation, change);
  });
}

function slashToHashbang(path) {
  return "!" + path.replace(/^\//, '');
}

function ensureSlash() {

  var path = HashbangLocation.getCurrentPath();
  if (path.charAt(0) === '/') {
    return true;
  }HashbangLocation.replace('/' + path);

  return false;
}

function onHashChange() {
  if (ensureSlash()) {
    // If we don't have an _actionType then all we know is the hash
    // changed. It was probably caused by the user clicking the Back
    // button, but may have also been the Forward button or manual
    // manipulation. So just guess 'pop'.
    var curActionType = _actionType;
    _actionType = null;
    notifyChange(curActionType || LocationActions.POP);
  }
}

/**
 * A Location that uses `window.location.hash`.
 */
var HashbangLocation = {

  addChangeListener: function addChangeListener(listener) {
    _listeners.push(listener);

    // Do this BEFORE listening for hashchange.
    ensureSlash();

    if (!_isListening) {
      if (window.addEventListener) {
        window.addEventListener('hashchange', onHashChange, false);
      } else {
        window.attachEvent('onhashchange', onHashChange);
      }

      _isListening = true;
    }
  },

  removeChangeListener: function removeChangeListener(listener) {
    _listeners = _listeners.filter(function (l) {
      return l !== listener;
    });

    if (_listeners.length === 0) {
      if (window.removeEventListener) {
        window.removeEventListener('hashchange', onHashChange, false);
      } else {
        window.removeEvent('onhashchange', onHashChange);
      }

      _isListening = false;
    }
  },

  push: function push(path) {
    _actionType = LocationActions.PUSH;
    window.location.hash = slashToHashbang(path);
  },

  replace: function replace(path) {
    _actionType = LocationActions.REPLACE;
    window.location.replace(window.location.pathname + window.location.search + '#' + slashToHashbang(path));
  },

  pop: function pop() {
    _actionType = LocationActions.POP;
    History.back();
  },

  getCurrentPath: function getCurrentPath() {
    return decodeURI(
    // We can't use window.location.hash here because it's not
    // consistent across browsers - Firefox will pre-decode it!
    "/" + (window.location.href.split('#!')[1] || ''));
  },

  toString: function toString() {
    return '<HashbangLocation>';
  }

};

module.exports = HashbangLocation;

请注意 slashToHashbang 函数。
那你就得

ReactRouter.create({location: HashbangLocation})

就是这样:-)

相关问题