[reactjs] react-router를 사용하여 브라우저에서 / # /을 중지하는 방법은 무엇입니까?

/#/react-router를 사용할 때 브라우저의 주소 표시 줄에 표시 되지 않도록 하는 방법이 있습니까? 그것은 ReactJS입니다. 즉, 링크를 클릭하여 새 경로로 이동하면 localhost:3000/#/또는
localhost:3000/#/about. 경로에 따라 다릅니다.



답변

react-router 버전 1, 2 및 3의 경우 URL 매핑 체계에 대한 경로를 설정하는 올바른 방법은 기록 구현을의 history매개 변수 에 전달하는 것 입니다 <Router>. 로부터 역사 문서 :

간단히 말해서 히스토리는 브라우저의 주소 표시 줄에서 변경 사항을 수신하는 방법을 알고 라우터가 경로를 일치시키고 올바른 구성 요소 집합을 렌더링하는 데 사용할 수있는 위치 개체로 URL을 구문 분석합니다.

버전 2 및 3

react-router 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 업그레이드 가이드

버전 4

다가오는 react-router 버전 4의 경우 구문이 크게 변경 BrowserRouter되었으며 라우터 루트 태그 로 사용하는 것이 필요합니다 .

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

Source React Router 버전 4 문서


답변

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

현재 버전 0.11 앞으로를 들어, 당신은 추가 할 필요 Router.HistoryLocationRouter.run(). <Routes>이제 더 이상 사용되지 않습니다. 0.12.x HistoryLocation 구현에 대한 업그레이드 가이드참조하십시오 .


답변

IE8을 지원할 필요가없는 경우 브라우저 기록을 사용할 수 있으며 react-router가 window.pushState해시를 설정하는 대신 사용 합니다.

이를 정확히 수행하는 방법은 사용중인 React Router의 버전에 따라 다릅니다.


답변

실제로 .htaccess를 사용하여이를 수행 할 수 있습니다. 브라우저에는 일반적으로 쿼리 문자열 구분 기호가 필요 ?하거나 #쿼리 문자열이 시작되고 디렉터리 경로가 끝나는 위치를 결정 해야합니다 . 우리가 원하는 최종 결과는 www.mysite.com/dir
웹 서버가 요청한 디렉토리를 검색하기 전에 문제를 파악해야합니다 /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을 사용하여 쿼리 매개 변수를 얻습니다.

그런 다음 원하는 경우 반응 경로를 사용하지 않고 원하는 경우 URL 및 브라우저 기록을 조작 할 수 있습니다. 이것이 누군가에게 도움이되기를 바랍니다 …


답변

히스토리 패키지 설치

npm install history --save

다음으로 히스토리에서 createHistory 및 useBasename 가져 오기

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 to="/somewhere">somewhere</Link>

솔루션의 영감은 React-Router 예제 에서 나왔는데
, 불행히도 API에 제대로 문서화되지 않았습니다.


답변

해시 후 표시 할 내용을 처리하는 또 다른 방법은 (따라서 pushState를 사용하지 않는 경우!) CustomLocation을 생성하고 ReactRouter 생성시로드하는 것입니다.

예를 들어, 크롤링을위한 Google 사양을 준수하기 위해 해시 뱅 URL (#!)을 사용하려면 다음과 같은 원본 HashLocation을 주로 복사하는 HashbangLocation.js 파일을 만들 수 있습니다.

'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})

그리고 그게 다야 🙂


답변