React 라우터가 URL을 변경하지만보기는 아님


87

라우팅에 반응하여보기를 변경하는 데 문제가 있습니다. 사용자 목록 만 표시하고 각 사용자를 클릭하면 세부 정보 페이지로 이동해야합니다. 라우터는 다음과 같습니다.

import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter } from 'react-router-dom';
import Users from "./components/Users";
import { Router, Route } from "react-router";
import Details from "./components/Details";

ReactDOM.render((
  <BrowserRouter>
    <div>
        <Route path="/" component={Users} />
        <Route path="/details" component={Details} />
    </div>
  </BrowserRouter>
), document.getElementById('app'))

url / details를 사용하면 브라우저가 해당 URL로 이동하지만보기를 변경하지 않습니다. 다른 경로는 404를 던지므로 경로를 인식하지만 업데이트하지 않는 것 같습니다.


두 가지 오류가 발생합니다. 하나는 기본 반응 패키지의 proptypes 사용이 더 이상 사용되지 않는다는 내용입니다. React.createClass를 사용하는 두 가지 진술은 더 이상 사용되지 않습니다. 코드가 라우팅을 사용하지 않고 작동하기 때문에 이것이 관련이 없다고 생각했습니다.
MARyan87 2017-04-11

부품이 올바르게 장착 되었습니까?
제레미 존

답변:


74

exactindexRoute 의 속성을 지정해야합니다 . 그렇지 않으면 짝수 /details경로의 경우 여전히 /. 또한 가져 오려고 Route에서react-router-dom

import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter, Route } from 'react-router-dom';
import Users from "./components/Users";

import Details from "./components/Details";

ReactDOM.render((
  <BrowserRouter>
    <div>
        <Route exact path="/" component={Users} />
        <Route path="/details" component={Details} />
    </div>
  </BrowserRouter>
), document.getElementById('app'))

최신 정보:

해야 할 또 다른 일은 구성 요소 사용자를 withRouter. 당신은 사용 할 필요가 withRouter구성 요소가 수신되지 않는 경우 만 Router props,

이는 구성 요소가 라우터에 의해 렌더링 된 구성 요소의 중첩 된 자식 이거나 라우터 속성을 전달하지 않았 거나 구성 요소가 라우터에 전혀 연결되지 않고 별도의 구성 요소로 렌더링되는 경우에 발생할 수 있습니다. 경로.

Users.js에서 추가

import {withRouter} from 'react-router';

.........
export default withRouter(Users)

문서


proptypes 경고는 React.PropsTypes를 설치 npm install -S 'prop-types'하고 PropTypes로 바꾸면 제거 할 수 있습니다 . 또한 여전히 React.PropTypes을 사용하고있을 수 있습니다 다른 패키지 이후 포장 된 최신의 메이크업에 사용하도록 package.json를 업데이트하고 React.createClass
하기 Shubham 카트리

URL이 경우 부하보고 변경할 때 또한 당신은 페이지를 다시로드하려고 마십시오
하기 Shubham 카트리

페이지를 다시로드하려고했지만보기가 변경되지 않습니다. Users (사용자)로로드 심지어 URL이 / # / 세부 사항보기
MARyan87

1
당신이 업데이트 된 답변을 시도 할 수 있습니다 Route'에서 가져온 반응-라우터 dom`을 대신react-router
하기 Shubham 카트리

아직 해결되지 않은 경우 사용자 구성 요소를으로 바인딩 withRouter하면 이전에 동일한 문제를 해결하는 데 도움이되었습니다. 알려주세요. 코드도 업데이트했습니다.
Shubham Khatri

27

withRouter 내부의 구성 요소를 감싸기 만하면 됩니다.

<Route exact path="/mypath" component={withRouter(MyComponent)} />

다음은 샘플 App.js 파일입니다.

...
import { BrowserRouter as Router, Route, Switch, withRouter } from "react-router-dom";
import Home from "./pages/Home";
import Profile from "./pages/Profile";

class App extends Component {
  render() {
    return (
      <Router>
        <Switch>
          <Route exact path="/" component={withRouter(Home)} />
          <Route exact path="/profile" component={withRouter(Profile)} />
        </Switch>
      </Router>
    );
  }
}

export default App;

추가

반응 라우터를 사용 하는 경우 URL이 변경 될 때마다 componentWillReceiveProps 가 호출됩니다.

componentWillReceiveProps(nextProps) {
    var currentProductId = nextProps.match.params.productId;
    var nextProductId = nextProps.match.params.productId; // from the new url
    ...
}

노트

또는 내보내기 전에 구성 요소를 withRouter로 래핑 할 수도 있지만 다른 몇 가지 사항을 확인해야합니다. 저는 보통이 단계를 건너 뜁니다.

export default withRouter(Profile)

3
<루트 정확한 경로 = "/ MYPATH"구성 요소 = {withRouter (를 MyComponent)} /> 나를 위해 일한
산토 쉬 쿠마

15

나는 같은 문제가 있었고 그것이 중첩 라우터가 있기 때문이라는 것을 발견했습니다. 중첩 된 라우터를 제거하고 구성 요소 별 경로를 스위치 구성 요소 내에 배치하면 withRouter를 사용하거나 추가 변경을 수행하지 않고도 문제가 해결되었습니다.

<Router> // <--Remove nested Router
    <Switch>
      <Route exact path="/workflows" component={ViewWorkflows} />
      <Route path="/workflows/new" component={NewWorkflow} />
    </Switch>
</Router>

Yusufbek도 비슷한 문제를 설명하고 있습니다. 구성 요소 관련 경로를 뷰 수준에서 저장하는 것이 하나의 주 라우터에 모두 저장하는 것보다 훨씬 깔끔하다고 생각합니다. 프로덕션 앱에서는 문제를 쉽게 읽고 디버깅하기에는 너무 많은 경로가 될 것입니다.


14

나는 같은 문제에 직면했지만 그것을 고쳤다. 마지막으로 홈페이지를 배치했습니다. 그것은 나를 위해 작동합니다. 아래와 같습니다.

    import React from "react";
    import ReactDOM from "react-dom";
    import { BrowserRouter } from 'react-router-dom';
    import Users from "./components/Users";
    import { Router, Route } from "react-router";
    import Details from "./components/Details";

    ReactDOM.render((
      <BrowserRouter>
        <div>
            <Route path="/details" component={Details} />
            <Route path="/" component={Users} />
        </div>
      </BrowserRouter>
    ), document.getElementById('app'))


5
exact속성을 사용하면 이 문제도 해결되었을 것입니다.
isherwood

8

Redux를 사용할 때 URL이 주소 표시 줄에서 업데이트되었지만 앱이 해당 구성 요소를로드하지 않는 유사한 문제가 발생했습니다. 내보내기에 withRouter를 추가하여 해결할 수있었습니다.

import { connect } from 'react-redux'
import { withRouter } from 'react-router-dom'

export default withRouter(connect(mapStateToProps)(MyComponentName))

7

비슷한 문제가 있었지만 구조가 다릅니다. 모든 경로를 처리 할 하나의 라우터를 추가했으며 스위치 구성 요소를 사용하여보기를 전환했습니다. 그러나 실제로는 그렇지 않았습니다. URL 만 변경되었지만 볼 수는 없습니다. 그 이유는 Router 컴포넌트 외부에있는 SideBar 컴포넌트 내부에 사용 된 Link 컴포넌트 때문입니다. (예, "withRouter"로 사이드 바를 내보냈지만 작동하지 않았습니다). 따라서 해결책은 모든 Link 구성 요소를 보유하는 SideBar 구성 요소를 라우터로 이동하는 것입니다.

문제는 내 링커에 있으며 라우터 외부에 있습니다.

<div className="_wrapper">
  <SideBar /> // Holds my all linkers
  <Router>
     <Switch>
       <Route path="/" component={Home} />
       <Route path="/users" component={Users} />
     </Switch>
  </Router>
 </div>

솔루션은 내 링커를 라우터로 이동하는 것이 었습니다.

<div className="_wrapper">
  <Router>
     <SideBar /> // Holds my all linkers
     <Switch>
       <Route path="/" component={Home} />
       <Route path="/users" component={Users} />
     </Switch>
  </Router>
</div>

3
자신을 돕는 것이 내 하루였습니다. 두 개의 분리 된 라우터로 시도했습니다. 하나는 navbar 내에 있고 다른 하나는 구성 요소를 수용하기 위해 본문 내에 있습니다. 이제 부모 구성 요소의 동일한 라우터에 모든 것을 배치하고 정상적으로 작동합니다.
Matteus Barbosa

3
우수-내 정확한 문제. 감사합니다
Geoffrey Bourne

2
감사! 넌 나를 구했다!!
AzizStark

1
나는 withRouter를 포함하여 모든 것을 시도했지만이 솔루션 만이 효과가있었습니다.이 문제가 발생하는 이유를 이해하는 데 약간의 설명이 도움이 될 것입니다
Jim

1
@Jim 나는 react-router가 컨텍스트 API를 사용한다고 생각하며, <Router />일명 , <BrowserRouter /> 같은 경로 매처 및 , 같은 탐색 구성 요소에 컨텍스트를 제공합니다 . 동일한 컨텍스트를 제공하려면 컨텍스트 공급자 내에서 모든 하위 구성 요소를 래핑해야합니다 . <Route /><Switch /><Link /><Redirect /><Router />
Yusufbek

6

제 경우에는 실수로 두 개의 BrowserRouters를 중첩했습니다 .


5

BrowserRouter는 귀하의 경우 기록을 유지하지 못합니다. 대신 "라우터"를 사용하세요. 커스텀 히스토리를 소품으로 사용하면 문제 해결에 도움이 될 수 있습니다.

import {Router, Route, Switch, withRouter } from "react-router-dom";
import Home from "./pages/Home";
import Profile from "./pages/Profile";
import {createBrowserHistory} from 'history';

export const customHistory = createBrowserHistory();  //This maintains custom history

class App extends Component {
  render() {
    return (
      <Router history={customHistory}>
        <Switch>
          <Route exact path="/" component={Home} />
          <Route exact path="/profile" component={Profile} />
        </Switch>
      </Router>
    );
  }
}

export default App;

그런 다음 구성 요소에서 'App'에서 customHistory를 가져 와서 탐색하는 데 사용합니다.

customHistory.push('/pathname');

희망이 도움이! :)


1
exact사용할 때 속성이 필요하지 않음Switch
KBT

4

당신은 인덱스 경로에 정확한 추가 할 필요가 오히려 그 둘러싸는보다 경로 사업부로 구성 요소를 사용하여 스위치 에서이 반응 라우터-DOM을 경로 전환합니다.

import React from "react";
import ReactDOM from "react-dom";
import { Route, Switch } from 'react-router-dom';
import Users from "./components/Users";

import Details from "./components/Details";

ReactDOM.render((
  <div>
    <Switch>
        <Route path="/" component={Users} exact/>
        <Route path="/details" component={Details} />
    </Switch>
  </div>
), document.getElementById('app'))

3

React Router 버전 4와 비슷한 문제가 있습니다.

<Link />구성 요소 를 클릭하면 URL이 변경되지만보기는 변경되지 않습니다.

보기 중 하나 PureComponentComponent(에서 가져옴 react) 대신 사용 하고 있었으며 그 원인이었습니다.

사용 된 모든 경로 렌더링 구성 요소를 대체함으로써 PureComponent로를 Component, 내 문제가 해결되었습니다.

(해결 출처 : https://github.com/ReactTraining/react-router/issues/4975#issuecomment-355393785 )


1
감사. 그것은 나를 위해 그것을 고쳤습니다. 그러나 라이브 뷰 변경이 작동하려면 PureComponent 대신 Component에서 확장해야하는 Switch가 포함 된 구성 요소뿐이었습니다.
Christiaan Westerbeek

1
순수한 구성 요소를 구성 요소로 변경했지만 저에게는 작동하지 않습니다.
Kosalram Rama Krishnan

2

나는 비슷한 문제에 직면하고 있었는데 이것처럼 해결하기 위해 노력하고 있기를 바랍니다.

구성 요소 에서 componentWillReceiveProps 함수 를 사용해야 합니다.

url www.example.com/content1/을 호출하여 링크를 처음 클릭하면 componentDidMount ()가 실행됩니다.

이제 다른 링크를 클릭하면 www.example.com/content2/ 동일한 구성 요소가 호출되지만 이번에는 prop이 변경되고 API를 호출하는 데 사용할 수있는 componentWillReceiveProps (nextProps) 아래에서이 새 prop에 액세스하거나 상태를 비워두고 새로 가져올 수 있습니다. 데이터.

componentWillReceiveProps(nextProps){
     //call your API and update state with new props
}

1

실제로보기를 전환하는 스위치가 없습니다.

이것은 라우터를 사용하여 랜딩 페이지에서 메인 사이트로 전환하는 방법입니다.

//index.jsx    
ReactDOM.render( (<BrowserRouter><App/></BrowserRouter>), document.getElementById('root') );


//App.jsx
render()
{
    return <div>
        <Switch>
            <Route exact path='/' component={Lander}/>
            <Route path='/vadatajs' component={Vadatajs}/>
        </Switch>
    </div>
}

https://jsfiddle.net/Martins_Abilevs/4jko7arp/11/

ups 나는 당신이 다른 라우터를 사용하는 것을 발견했습니다. 죄송합니다. 그러면이 바이올린이 유용 할 것입니다.

https://fiddle.jshell.net/terda12/mana88Lm/

솔루션의 핵심은 메인 렌더링 기능에 숨겨져있을 수 있습니다.

Router.run(routes, function(Handler) {
    React.render(<Handler />, document.getElementById('container'));
});

1

같은 문제가 발생합니다. 이 경우에 그는 Prop withRouter를 추가해야한다고 생각하지 않습니다. NavLink를 확인하여 좋은 경로 이름을 세부 사항으로 작성하십시오. 경로의 경우 특정 경로에서 일반 경로로 시작하십시오.

<Route path="/details" component={Details} />
<Route path="/" component={Users} />

NavLink에서 다음과 같아야합니다.

 <NavLink className="nav-link" to="/details">
   details<span className="sr-only">(current)</span>
 </NavLink>

가져 오기에 대한 재 표현은 다음과 같은 다른 모듈을 가져온 후 React와 관련된 모든 항목을 가져 오는 것으로 시작하는 것이 좋습니다.

import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter } from 'react-router-dom';
import Users from "./components/Users";
import { Router, Route } from "react-router";
import Details from "./components/Details";

이렇게 오세요 :

import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter } from 'react-router-dom';
import { Router, Route } from "react-router";

import Users from "./components/Users";    
import Details from "./components/Details";

1

나를 위해 나는 :

export MyClass extends React.Component

와:

export default withRouter(MyClass)

한편, 내 App.js에서 다음과 같이했습니다.

import { MyClass } from './MyClass'

홈 게임을하는 사람들은 내 문제를 볼 수 있습니다. 라우터가 자식 클래스로 전달 된 가져 오기를 가져 오지 못했습니다. 이를 정리하기 위해 withRouter 호출을 Route 구성 요소 선언으로 이동했습니다 .

<Router exact path={'/myclass'} component={withRouter(MyClass)} />

MyClass로 돌아가서 기본 내보내기로 변경했습니다.

export default MyClass extends React.Component

그리고 마지막으로 App.js에서 가져 오기를 다음과 같이 변경했습니다.

import MyClass from './MyClass'

바라건대 이것은 누군가를 도울 것입니다. 이렇게하면 동일한 클래스를 내보내는 두 가지 방법이 없어서 withRouter 접두사 를 우회 할 수 있습니다.


0

이 시도,

import React from "react";

import ReactDOM from "react-dom";
import Users from "./components/Users";
import { Router, Route } from "react-router";


import Details from "./components/Details";

ReactDOM.render((
  <Router>
        <Route path="/" component={Wrapper} >
            <IndexRoute component={Users} />
            <Route path="/details" component={Details} />
        </Route>
  </Router>
), document.getElementById('app'))

this.props.children을 렌더링 할 래퍼 구성 요소를 정의합니다. 이것은 올바르게 라우팅됩니다.
Vaibhav Singh


0

조건부 레이아웃과 비슷한 문제가 있습니다.

class LayoutSwitcher extends Component {
  render () {
    const isLoggedIn = this.props.isLoggedIn
    return (
      <React.Fragment>
        { isLoggedIn
          ? <MainLayout {...this.props} />
          : <Login />
        }
      </React.Fragment>
    )
  }
}

다음과 같이 조건을 다시 작성했습니다.

  render () {
    const isLoggedIn = this.props.isLoggedIn
    if (isLoggedIn) {
      return <MainLayout {...this.props} />
    }
    return <Login />
  }

이것은 그것을 해결했습니다. 제 경우에는 맥락이 사라진 것 같습니다.



0

나는 같은 문제가 있었고 node_modules의 @types 폴더에서 기록을 가져 오는 것을 수정했습니다. npm (npm i @history)에서 가져 왔습니다.


0

나도 같은 문제가 있었다. 매우 효과적인 솔루션은 아니지만 교활한 방법으로 해결했습니다. ComponentDidMount 메서드는 URL이 변경 될 때마다 작동합니다. 메소드 내에서 이전 URL을 현재 URL과 비교할 수 있으며 상태 변경 또는 페이지 새로 고침을 수행 할 수 있습니다.

componentDidUpdate(prevProps) {
    if (this.props.match.url !== prevProps.match.url) {
        //this.props.history.go(0) refresh Page
        //this.setState(...) or change state
    }
}

-1

나도 문제를 만났다.

https://github.com/chengjianhua/templated-operating-system

그리고 Shubham Khatri가 제시 한 솔루션을 시도했지만 작동하지 않습니다.


이 문제를 해결했습니다. 도움이 될 수 있습니다.

https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/guides/blocked-updates.md

위 가이드 문서에 따르면 , ... PureComponent와 같은 상태 관리 도구 를 사용 하거나 함께 사용하면 경로 업데이트가 차단 될 수 있습니다. 경로 구성 요소를 확인하고 구성 요소에서 다시 렌더링을 차단하지 않았는지 확인하십시오.reduxmobx


-2

BrowserRouter (Router)에 prop forceRefresh = {true}를 추가하십시오.

import {BrowserRouter as Router} from "react-router-dom";

<Router forceRefresh={true}>
/// your <switch> and <route>
</Router>

그것은 나를 위해 작동합니다.

btw 실제 솔루션이 아닙니다 : D

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.