Bạn không nên sử dụng <Link> bên ngoài <Router>


80

Tôi đang cố thiết lập bộ định tuyến phản ứng trong một ứng dụng mẫu và gặp lỗi sau:

You should not use <Link> outside a <Router>

Ứng dụng của tôi được thiết lập như vậy:

Thành phần chính

const router = (
  <div className="sans-serif">
    <Router histpry={browserHistory}>
      <Route path="/" component={Main}>
        <IndexRoute component={PhotoGrid}></IndexRoute>
        <Route path="/view/:postId" component={Single}></Route>
      </Route>
    </Router>
  </div>
);

render(<Main />, document.getElementById('root'));

Con / Mainthành phần

export default () => (
  <div>
    <h1>
      <Link to="/">Redux example</Link>
    </h1>
  </div>
)

Bất kỳ ý tưởng những gì tôi đang làm sai ở đây?

Đây là liên kết Hộp cát để giải thích vấn đề.


Vui lòng đề cập đến phiên bản bạn đang sử dụng react-router, Vì bạn đang sử dụng các cách tiếp cận khác nhau cho Định tuyến chỉ mục.
Haider Ali Anjum

Tôi nhận được thông báo này do không thể tải lại nóng sau khi cập nhật một số phần phụ thuộc của ứng dụng. Thoát và khởi động lại máy chủ phát triển theo cách thủ công đã giải quyết được sự cố. Chỉ FYI trong trường hợp ai đó có tin nhắn bật lên từ hư không.
ballenf

Câu trả lời:


54

Tôi giả định rằng bạn đang sử dụng React-Router V4, như bạn đã sử dụng cùng trong Liên kết hộp cát ban đầu .

Bạn đang hiển thị Mainthành phần trong cuộc gọi đến ReactDOM.renderđó hiển thị a Linkvà Thành phần chính nằm ngoài Router, đó là lý do tại sao nó gặp lỗi:

Bạn không nên sử dụng <Link> bên ngoài <Router>

Các thay đổi :

  1. Sử dụng bất kỳ một trong các Bộ định tuyến này , BrowserRouter / HashRouter, v.v., vì bạn đang sử dụng React-Router V4.

  2. Bộ định tuyến chỉ có thể có một con, vì vậy hãy gói tất cả các tuyến trong một divhoặc Bộ chuyển mạch .

  3. React-Router V4, không có khái niệm về các tuyến lồng nhau, nếu bạn muốn sử dụng các tuyến lồng nhau thì hãy xác định các tuyến đó trực tiếp bên trong thành phần đó.


Kiểm tra ví dụ làm việc này với từng thay đổi.

Thành phần chính:

const App = () => (
  <BrowserRouter>
    <div className="sans-serif">
      <Route path="/" component={Main} />
      <Route path="/view/:postId" component={Single} />
    </div>
  </BrowserRouter>
);

render(<App />, document.getElementById('root'));

Main thành phần từ tuyến đường

import React from 'react';
import { Link } from 'react-router-dom';

export default () => (
  <div>
    <h1>
      <Link to="/">Redux example</Link>
    </h1>
  </div>
)

Vân vân.


Cũng kiểm tra câu trả lời này: Các tuyến đường lồng nhau với bộ định tuyến phản ứng v4


72

Đối với JEST người dùng

nếu bạn sử dụng Jest để thử nghiệm và lỗi này xảy ra, chỉ cần bọc thành phần của bạn bằng <BrowserRouter>

describe('Test suits for MyComponentWithLink', () => {
it('should match with snapshot', () => {
const tree = renderer
  .create(
    <BrowserRouter>
      <MyComponentWithLink/>
    </BrowserRouter>
  )
  .toJSON();
 expect(tree).toMatchSnapshot();
 });
});

4
Bạn đã cứu tôi. Cảm ơn
StrugglingCoder

2
Chính xác những gì tôi đang tìm kiếm. Cảm ơn bạn
digitalh2o 11/12/19

@MBehtemam, bạn đã cứu một ngày của tôi!
lmiguelvargasf

@MBehtemam, thx cho sự bổ sung tuyệt vời. Nó đã làm việc cho tôi.
Mo1

Câu trả lời này sử dụng react-test-renderer, không được tích hợp sẵn cho ứng dụng tạo. Nếu bạn sử dụng cài sẵn @testing-library/react, hãy sử dụng render(<BrowserRouter><MyComponent/></BrowserRouter>);thay thế.
Timmy Chan

11

Bao gồm thành phần Liên kết bên trong thành phần BrowserRouter

 export default () => (
  <div>
   <h1>
      <BrowserRouter>
        <Link to="/">Redux example</Link>
      </BrowserRouter>
    </h1>
  </div>
)

7

Bất cứ khi nào bạn cố gắng hiển thị Linktrên một trang bên ngoài, BrowserRouterbạn sẽ gặp lỗi đó.

Thông báo lỗi này về cơ bản nói rằng bất kỳ thành phần nào không phải là con của chúng tôi <Router> đều không thể chứa bất kỳ thành phần nào liên quan đến Bộ định tuyến React.

Bạn cần di chuyển phân cấp thành phần của mình theo cách bạn thấy trong câu trả lời đầu tiên ở trên. Đối với bất kỳ ai khác xem xét bài đăng này, người có thể cần xem thêm các ví dụ.

Giả sử bạn có một Header.jsthành phần trông giống như sau:

import React from 'react';
import { Link } from 'react-router-dom';

const Header = () => {
    return (
        <div className="ui secondary pointing menu">
            <Link to="/" className="item">
                Streamy
            </Link>
            <div className="right menu">
                <Link to="/" className="item">
                    All Streams
                </Link>
            </div>
        </div>
    );
};

export default Header;

App.jstệp của bạn trông như thế này:

import React from 'react';
import { BrowserRouter, Route, Link } from 'react-router-dom';
import StreamCreate from './streams/StreamCreate';
import StreamEdit from './streams/StreamEdit';
import StreamDelete from './streams/StreamDelete';
import StreamList from './streams/StreamList';
import StreamShow from './streams/StreamShow';
import Header from './Header';

const App = () => {
  return (
    <div className="ui container">
      <Header />
      <BrowserRouter>
        <div>
        <Route path="/" exact component={StreamList} />
        <Route path="/streams/new" exact component={StreamCreate} />
        <Route path="/streams/edit" exact component={StreamEdit} />
        <Route path="/streams/delete" exact component={StreamDelete} />
        <Route path="/streams/show" exact component={StreamShow} />
        </div> 
      </BrowserRouter>
    </div>
  );
};

export default App;

Lưu ý rằng Header.jsthành phần đang sử dụng Linkthẻ từ react-router-domnhưng các thành phần được đặt bên ngoài <BrowserRouter>, điều này sẽ dẫn đến lỗi giống như một trải nghiệm của OP. Trong trường hợp này, bạn có thể thực hiện điều chỉnh bằng một động tác:

import React from 'react';
import { BrowserRouter, Route } from 'react-router-dom';
import StreamCreate from './streams/StreamCreate';
import StreamEdit from './streams/StreamEdit';
import StreamDelete from './streams/StreamDelete';
import StreamList from './streams/StreamList';
import StreamShow from './streams/StreamShow';
import Header from './Header';

const App = () => {
  return (
    <div className="ui container">
      <BrowserRouter>
        <div>
        <Header />
        <Route path="/" exact component={StreamList} />
        <Route path="/streams/new" exact component={StreamCreate} />
        <Route path="/streams/edit" exact component={StreamEdit} />
        <Route path="/streams/delete" exact component={StreamDelete} />
        <Route path="/streams/show" exact component={StreamShow} />
        </div> 
      </BrowserRouter>
    </div>
  );
};

export default App;

Vui lòng xem lại cẩn thận và đảm bảo bạn có <Header />hoặc bất cứ thành phần của bạn có thể bên trong không chỉ <BrowserRouter>mà còn bên trong <div>, nếu không bạn cũng sẽ nhận được những lỗi mà một Router chỉ có thể có một đứa trẻ được đề cập đến <div>đó là con của <BrowserRouter>. Mọi thứ khác chẳng hạn nhưRoute và các thành phần phải đi trong nó trong hệ thống phân cấp.

Vì vậy, bây giờ <Header />là con của <BrowserRouter>các <div>thẻ bên trong và nó có thể sử dụng thành công Linkphần tử.


3

Tôi nghĩ ra mã này:

import React from 'react';
import { render } from 'react-dom';

// import componentns
import Main from './components/Main';
import PhotoGrid from './components/PhotoGrid';
import Single from './components/Single';

// import react router
import { Router, Route, IndexRoute, BrowserRouter, browserHistory} from 'react-router-dom'

class MainComponent extends React.Component {
  render() {
    return (
      <div>
        <BrowserRouter history={browserHistory}>
          <Route path="/" component={Main} >
            <IndexRoute component={PhotoGrid}></IndexRoute>
            <Route path="/view/:postId" component={Single}></Route>
          </Route>
        </BrowserRouter>
      </div>
    );
  }
}

render(<MainComponent />, document.getElementById('root'));

Tôi nghĩ rằng lỗi là do bạn đang kết xuất Mainthành phần và Mainthành phần đó không biết gì về nó Router, vì vậy bạn phải kết xuất thành phần cha của nó.


2

Làm nó đơn giản:

render(<BrowserRouter><Main /></BrowserRouter>, document.getElementById('root'));

và đừng quên: import { BrowserRouter } from "react-router-dom";


1

Tôi gặp lỗi này vì tôi đang nhập thành phần có thể sử dụng lại từ thư viện npm và các phiên bản của react-router-domkhông khớp.

Vì vậy, hãy đảm bảo rằng bạn sử dụng cùng một phiên bản ở cả hai nơi!


0

Viết bộ định tuyến thay cho Chính trong kết xuất (dòng cuối cùng trong mã). Giống như ReactDOM.render này (router, document.getElementById ('root'));


0

Bạn có thể đặt thành phần Liên kết bên trong các thành phần Bộ định tuyến. Một cái gì đó như thế này:

 <Router>
        <Route path='/complete-profiles' component={Profiles} />
        <Link to='/complete-profiles'>
          <div>Completed Profiles</div>
        </Link>
      </Router>

-12

Nếu bạn không muốn thay đổi nhiều, hãy sử dụng mã bên dưới bên trong phương thức onClick ().

this.props.history.push('/');
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.