Bộ định tuyến phản ứng thay đổi url nhưng không xem được


82

Tôi gặp sự cố khi thay đổi chế độ xem trong phản ứng với định tuyến. Tôi chỉ muốn hiển thị danh sách người dùng và nhấp vào mỗi người dùng sẽ điều hướng đến trang chi tiết. Đây là bộ định tuyến:

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

Khi tôi sử dụng url / chi tiết, trình duyệt của tôi điều hướng đến url đó, nhưng không thay đổi chế độ xem. Bất kỳ tuyến đường nào khác ném 404 để nó có vẻ nhận ra tuyến đường nhưng không cập nhật.


Tôi nhận được hai lỗi: Một lỗi nói rằng việc sử dụng proptypes từ gói phản ứng chính không được dùng nữa. Hai tuyên bố sử dụng React.createClass không được dùng nữa. Tôi nghĩ rằng điều này là không liên quan, vì mã hoạt động mà không cần sử dụng định tuyến.
MARyan87

Có phải linh kiện của bạn đang lắp chính xác?
Jeremy John

Câu trả lời:


70

Bạn cần chỉ định thuộc tính exactcho indexRoute của mình, nếu không, đối với /detailstuyến chẵn, nó vẫn sẽ khớp với /. Cũng cố gắng nhập Routetừ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'))

CẬP NHẬT:

Một điều khác mà bạn cần làm là đính kèm Người dùng thành phần của bạn với withRouter. Bạn chỉ cần sử dụng withRouterkhi thành phần của bạn không nhận được Router props,

Điều này có thể xảy ra trong các trường hợp khi thành phần của bạn là con lồng nhau của một thành phần được Bộ định tuyến hiển thị hoặc bạn chưa chuyển các đạo cụ Bộ định tuyến cho nó hoặc khi thành phần đó hoàn toàn không được liên kết với Bộ định tuyến và được hiển thị như một thành phần riêng biệt từ các tuyến đường.

Trong Users.js thêm

import {withRouter} from 'react-router';

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

DOCS


Cảnh báo proptypes có thể được gỡ bỏ bằng cách cài đặt npm install -S 'prop-types'và thay thế React.PropsTypes bằng PropTypes. Cũng cập nhật package.json của bạn để làm cho sử dụng mới nhất được đóng gói từ gói khác vẫn có thể sử dụng React.PropTypes và React.createClass
Shubham Khatri

Ngoài ra Bạn có cố gắng tải lại trang khi url thay đổi để xem nếu nó tải
Shubham Khatri

Tôi đã thử tải lại trang, nó không thay đổi chế độ xem. Nó tải vào chế độ xem Người dùng ngay cả khi url là / # / details
MARyan87

1
Bạn có thể thử các câu trả lời được cập nhật với Routenhập khẩu từ 'phản ứng-router-dom` thay vìreact-router
Shubham Khatri

Nếu nó vẫn chưa được giải quyết, hãy liên kết thành phần người dùng của bạn với withRouter, nó đã giúp tôi giải quyết vấn đề tương tự trước đây. Cho tôi biết. Tôi cũng đã cập nhật mã.
Shubham Khatri

27

Bạn chỉ cần bọc các thành phần bên trong bằngRouter .

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

Đây là tệp App.js mẫu:

...
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;

Bổ sung

Nếu bạn đang sử dụng bộ định tuyến phản ứng, componentWillReceiveProps sẽ được gọi bất cứ khi nào url thay đổi.

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

Ghi chú

Ngoài ra, bạn cũng có thể bọc thành phần trong withRouter trước khi xuất, nhưng sau đó bạn phải đảm bảo một số điều khác. Tôi thường bỏ qua bước này.

export default withRouter(Profile)

3
<Route precision path = "/ mypath" component = {withRouter (MyComponent)} /> phù hợp với tôi
Santosh Kumar

14

Tôi đã gặp vấn đề tương tự và phát hiện ra rằng đó là do tôi có một bộ định tuyến lồng nhau. Sau khi tôi xóa bộ định tuyến lồng nhau và chỉ cần đặt các tuyến đường dành riêng cho thành phần của mình trong một thành phần chuyển mạch - sự cố đã được giải quyết mà không cần phải sử dụng withRouter hoặc thực hiện bất kỳ thay đổi bổ sung nào.

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

Yusufbek đang mô tả một vấn đề tương tự. Tôi nghĩ lưu trữ các tuyến liên quan đến thành phần ở cấp chế độ xem sẽ gọn gàng hơn nhiều so với lưu trữ tất cả chúng trong một bộ định tuyến chính. Trong một ứng dụng sản xuất, đó sẽ là quá nhiều tuyến đường để có thể dễ dàng đọc qua và gỡ lỗi các vấn đề.


13

Tôi đã phải đối mặt với vấn đề tương tự nhưng tôi đã sửa nó. Tôi đã đặt trang chủ là trang cuối cùng. Nó làm việc cho tôi. Cũng giống như bên dưới.

    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
Sử dụng thuộc exacttính cũng sẽ giải quyết điều này cho bạn.
isherwood

Vâng, bạn đã đúng.
Shahab Khan

8

Khi sử dụng Redux và tôi gặp sự cố tương tự trong đó url đang cập nhật trong thanh địa chỉ nhưng ứng dụng không tải thành phần tương ứng. Tôi đã có thể giải quyết bằng cách thêm withRouter vào phần xuất:

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

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

5

Tôi đã có một vấn đề tương tự nhưng với cấu trúc khác nhau. Tôi đã thêm một Bộ định tuyến sẽ xử lý tất cả các tuyến đường, tôi đã sử dụng thành phần Switch để chuyển đổi chế độ xem. Nhưng thực ra thì không. Chỉ URL được thay đổi nhưng không có chế độ xem. Lý do cho điều này là thành phần Liên kết được sử dụng bên trong thành phần SideBar nằm bên ngoài thành phần Bộ định tuyến. (Có, tôi đã xuất SideBar bằng "withRouter", không hoạt động). Vì vậy, giải pháp là di chuyển thành phần SideBar chứa tất cả các thành phần Liên kết vào Bộ định tuyến của tôi.

Vấn đề là ở các trình liên kết của tôi, chúng nằm ngoài bộ định tuyến của tôi

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

Giải pháp đã chuyển các trình liên kết của tôi vào bộ định tuyến của tôi

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

2
giúp chính mình làm nên ngày của tôi. Tôi đã thử nó với hai Bộ định tuyến riêng biệt. Một bên trong thanh điều hướng và một bên trong phần thân để chứa thành phần. Bây giờ tôi đặt mọi thứ trong cùng một Bộ định tuyến trong thành phần mẹ và mọi thứ hoạt động như bình thường.
Matteus Barbosa

3
Tuyệt vời - vấn đề chính xác của tôi. Cảm ơn bạn
Geoffrey Bourne

2
Cảm ơn! Bạn đã cứu tôi!!
AzizStark

5

Trong trường hợp của tôi, tôi đã lồng nhầm hai chữ BrowserRouters.


5

BrowserRouter không duy trì lịch sử trong trường hợp của bạn. Sử dụng "Bộ định tuyến" thay thế, Việc sử dụng cái này với lịch sử tùy chỉnh làm đạo cụ có thể giúp giải quyết sự cố của bạn.

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;

Sau đó, trong các thành phần của bạn, hãy nhập customHistory từ 'Ứng dụng' và sử dụng nó để điều hướng.

customHistory.push('/pathname');

Hy vọng điều này giúp đỡ! :)


1
không cần exactthuộc tính khi bạn sử dụngSwitch
KBT

4

Bạn cần thêm chính xác vào tuyến chỉ mục và thay vì bao quanh các thành phần Tuyến đó bằng div, hãy sử dụng Chuyển từ react-router-dom để chuyển đổi giữa các tuyến.

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

Tôi đã gặp sự cố tương tự với React Router phiên bản 4:

Bằng cách nhấp vào <Link />thành phần, URL sẽ thay đổi nhưng lượt xem thì không.

Một trong những lượt xem đã được sử dụng PureComponentchứ không phải Component(được nhập từ react) và đó là nguyên nhân.

Bằng cách thay thế tất cả các thành phần tuyến đường trả lại được sử dụng PureComponentđể Component, vấn đề của tôi đã được giải quyết.

(Nguồn phân giải: https://github.com/ReactTraining/react-router/issues/4975#issuecomment-355393785 )


1
Cảm ơn. Điều đó đã sửa nó cho tôi. Nhưng nó chỉ là thành phần chứa Switch mà tôi phải mở rộng từ Component thay vì PureComponent để chế độ xem trực tiếp hoạt động.
Christiaan Westerbeek

Tôi đã thay đổi thành phần thuần túy của mình thành thành phần, mặc dù vậy, nó không hoạt động với tôi.
Kosalram Rama Krishnan, 13/09/19

1

Hmm không có bất kỳ CHUYỂN ĐỔI nào để thực sự chuyển đổi chế độ xem.

đây là cách tôi sử dụng bộ định tuyến để chuyển từ trang landin sang trang chính

//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/

up tôi thấy bạn sử dụng bộ định tuyến khác nhau .. xin lỗi vì vậy có thể điều này sẽ hữu ích cho bạn

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

có thể chìa khóa của giải pháp được ẩn trong dòng cho chức năng kết xuất chính ..

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

1

Tôi đã gặp phải vấn đề tương tự, tôi quyết tâm giải quyết vấn đề này, vui lòng xem xét tôi hy vọng nó hoạt động.

Bạn cần sử dụng chức năng componentWillReceiveProps trong thành phần của mình.

đã nhấp vào liên kết lần đầu tiên bằng cách chạy url www.example.com/content1/ componentDidMount ().

Bây giờ khi bạn nhấp vào một liên kết khác nói rằng www.example.com/content2/ cùng một thành phần được gọi nhưng lần này prop thay đổi và bạn có thể truy cập vào phần hỗ trợ mới này trong componentWillReceiveProps (nextProps) mà bạn có thể sử dụng để gọi API Hoặc đặt trạng thái trống và nhận mới dữ liệu.

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

1

Đối với tôi, tôi đã có:

export MyClass extends React.Component

với:

export default withRouter(MyClass)

Trong khi đó, trong App.js của tôi, tôi có:

import { MyClass } from './MyClass'

Những người chơi trò chơi tại nhà có thể thấy vấn đề của tôi. Tôi đã không nhận được nhập với Bộ định tuyến được chuyển vào các lớp con. Để làm sạch điều này, tôi đã chuyển lời gọi withRouter vào khai báo thành phần Route:

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

Quay lại MyClass, tôi đã thay đổi nó thành xuất mặc định:

export default MyClass extends React.Component

Và cuối cùng, trong App.js, tôi đã thay đổi quá trình nhập của mình thành:

import MyClass from './MyClass'

Hy vọng rằng điều này sẽ giúp ai đó. Điều này đảm bảo rằng tôi không có hai cách để xuất cùng một lớp, do đó bỏ qua việc thêm trước withRouter .


0

Thử đi,

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

Xác định một thành phần Wrapper sẽ hiển thị this.props.children. Điều này sẽ định tuyến đúng cách.
Vaibhav Singh


0

Tôi đã gặp sự cố tương tự với Bố cục có điều kiện:

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

và viết lại các điều kiện như sau:

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

Điều này đã giải quyết nó. Trong trường hợp của tôi, có vẻ như bối cảnh đã bị mất.


0

Tôi nhận được cùng một vấn đề. Tôi không nghĩ rằng trong trường hợp này anh ta cần thêm phần mềm hỗ trợ vớiRouter, chỉ cần kiểm tra NavLink của bạn, bạn viết tên đường dẫn tốt làm chi tiết. đối với tuyến đường cố gắng bắt đầu từ tuyến đường cụ thể đến tuyến đường chung như

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

trong NavLink của bạn, nó sẽ giống như thế này

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

remarque để bắt đầu nhập tốt hơn bằng cách nhập tất cả nội dung liên quan đến React sau đó nhập mô-đun khác như mô-đun này:

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";

đến như thế này:

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";

0

Trong trường hợp của tôi, chuyển sang HashRouter thay vì BrowserRouter đã giải quyết được sự cố của tôi


0

Tôi gặp sự cố tương tự và tôi đã khắc phục sự cố khi nhập lịch sử từ thư mục @types trong node_modules. Tôi đã nhập nó từ npm (npm i @history)


-1

Tôi cũng gặp rắc rối.

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

Và tôi đã thử các giải pháp do Shubham Khatri đấu giá, nhưng nó không hoạt động.


Tôi đã giải quyết vấn đề này, có thể có thể giúp bạn.

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

Theo tài liệu hướng dẫn trên, khi bạn sử dụng PureComponenthoặc sử dụng với các công cụ quản lý nhà nước như redux, mobx... Nó có thể chặn việc cập nhật lộ trình của bạn. Kiểm tra thành phần tuyến đường của bạn, đảm bảo bạn không chặn kết xuất od thành phần của bạn.


-2

cố gắng thêm prop forceRefresh = {true} vào BrowserRouter (Bộ định tuyến)

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

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

nó hoạt động cho tôi.

btw nó không phải là một giải pháp thực sự: D

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.