programing

외부에서는 사용하지 마십시오.

batch 2023. 3. 12. 10:37
반응형

외부에서는 사용하지 마십시오.

샘플 어플리케이션에서 리액트라우터를 설정하려고 하는데 다음 오류가 나타납니다.

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

앱은 다음과 같이 설정되어 있습니다.

상위 컴포넌트

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

아이/Main요소

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

내가 여기서 뭘 잘못하고 있는지 알기나?

문제를 보여주는 Sandbox 링크입니다.

JEST 사용자의 경우

테스트에 Jest를 사용했는데 이 오류가 발생하면 컴포넌트를 랩으로 감싸기만 하면 됩니다.<BrowserRouter>

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

원래 Sandbox Link에서 사용하던 것과 마찬가지로 React-Router V4를 사용하고 있다고 가정합니다.

렌더링 중Main호출 컴포넌트ReactDOM.render이 경우,Link메인 컴포넌트는 외부로,Router이 때문에 에러가 발생하고 있습니다.

<라우터> 밖에서 <링크>를 사용하지 마십시오.

변경 사항:

  1. React-Router V4 를 사용하고 있기 때문에, 다음의 라우터(BrowserRouter/HashRouter 등) 중 하나를 사용합니다.

  2. 라우터에는 자식은 1개뿐이므로 모든 루트를 1개의 포트로 랩합니다.div또는 전환합니다.

  3. React-Router V4에는 네스트된 루트의 개념이 없습니다.네스트된 루트를 사용하려면 해당 컴포넌트 내에서 직접 이들 루트를 정의합니다.


이 작업 예에서는 각 변경 사항을 확인하십시오.

상위 컴포넌트:

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루트로부터의 컴포넌트

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

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

기타.


다음 답변도 확인해 주세요.리액트 라우터 v4를 사용한 네스트된 루트

Link 컴포넌트를 BrowserRouter 컴포넌트 내에 포함

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

항상 당신이 그것을 보여주려고 할 때Link바깥쪽에 있는BrowserRouter에러가 납니다.

이 에러 메시지는 기본적으로 델의 자회사가 아닌 컴포넌트는<Router>에는 React Router 관련 컴포넌트를 포함할 수 없습니다.

컴포넌트 계층을 위의 첫 번째 답변에서 보는 방식으로 이행해야 합니다.이 투고를 리뷰하고 있는 다른 분들을 위해 더 많은 예를 참조할 필요가 있을 수 있습니다.

예를 들면,Header.js다음과 같은 컴포넌트:

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.js파일은 다음과 같습니다.

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;

주의:Header.js컴포넌트는 를 사용하고 있습니다.Link에서 꼬리표를 붙이다.react-router-dom컴포넌트는 외부로 배치되어 있습니다.<BrowserRouter>이 경우 OP에서 발생한 것과 동일한 오류가 발생합니다.이 경우 한 번에 수정할 수 있습니다.

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;

주의 깊게 검토하여 다음 사항을 확인하십시오.<Header />또는 컴포넌트가 내부뿐만 아니라<BrowserRouter>내부도 마찬가지입니다.<div>그렇지 않으면 라우터가 1개의 자식만 가질 수 있다는 오류도 발생합니다.<div>의 자식이다<BrowserRouter>: ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★)Route컴포넌트는 계층 내의 컴포넌트 내에 있어야 합니다.

, 그럼 이제...<Header />의 자녀입니다.<BrowserRouter>의 범위 내에서<div> 및 태그는 할 수 .Link★★★★★★ 。

심플화:

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

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

에서 재사용 가능한 컴포넌트를 이고,npm의 버전이기 때문에 하고 있습니다.react-router-dom일치하지 않습니다.

따라서 두 곳에서 동일한 버전을 사용해야 합니다.

이런 코드가 생각나네요

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

내 생각엔 네가 그 그림을 렌더링하고 있어서 그런 것 같아.Main " " " 입니다.Main 요소는 didn didn포포 component component component component component component component 에 대해 아무것도 알지 Router아버지 컴포넌트를 렌더링해야 합니다.

이것을 인덱스에 추가합니다.

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

해 주세요.<App />의 범위 내에서<Router></Router>리액트 어플리케이션 내의 링크를 사용합니다.

다음과 같습니다.

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

import App from "./App";

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

"react-router-dom"에서 BrowserRouter만 사용하는 다른 컴포넌트를 만들고 그 안에 있는 링크를 사용하여 컴포넌트를 랩합니다.

const ReduxExample () => (
  <div>
    <h1>
      <Link to="/">Redux example</Link>
    </h1>
  </div>
)

그러면 할 수 있어

const NewReduxExample = () => {
   <BrowserRouter>
     <ReduxExample />
   </BrowserRouter>
};

또는 src 폴더의 index.js 파일에서 이 작업을 수행할 수도 있습니다.

import React from 'react'; import ReactDOM from 'react-dom'; import { BrowserRouter as Router } from 'react-router-dom';

import App from './App';

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

그런 다음 Component.jsx 파일에서 링크를 가져올 수 있습니다.

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

라우터/루트 태그 없이 이와 같이 링크를 사용합니다.

<Link to="/">Page</Link>

다음과 같이 reactDom.render를 호출하는 BrowserRouter 내의 모든 컴포넌트를 랩합니다.

import {BrowserRouter} from 'react-router-dom'

ReactDOM.render(

  <React.StrictMode>
    <BrowserRouter>
    <App />
    </BrowserRouter>
  </React.StrictMode>,
  document.getElementById('root')
);

렌더의 메인(코드의 마지막 줄) 대신 라우터를 씁니다.이 ReactDOM.render(router, document.getElementById('root'))와 같습니다.

는 이 기사에 근거해 대답한다.여기 간단한 해결책이 있습니다.

// index.test.tsx
import React from "react";
import { render, screen } from "@testing-library/react";
import { Router } from "react-router-dom";
import { createBrowserHistory } from "history";
import Login from ".";

it("should display Login", () => {
  const history = createBrowserHistory();
  render(
    <Router history={history}>
      <Login />
    </Router>
  );
  const linkElement = screen.getByText(/Login/i);
  expect(linkElement).toBeInTheDocument();
});

다음은 솔루션입니다. 저는 create-react-app과 함께 제공되는 리액트 테스트 라이브러리를 사용합니다.문의하신 내용에 대한 간단한 해결방법은 알고 있습니다만, 다른 답변에서 수입품이 누락되어 있기 때문에 일괄적으로 기재해 두었습니다.테스트 파일은 다음과 같습니다.

// HomePage.test.js 
import { render, screen } from '@testing-library/react';
import { BrowserRouter } from 'react-router-dom';
import HomePage from './HomePage';

it('Homepage contains heading 1', () => {
  render(
    <BrowserRouter>
      <HomePage />
    </BrowserRouter>
  );

  screen.getByRole('heading', { level: 1 });
});

it('Homepage contains link', () => {
  render(
    <BrowserRouter>
      <HomePage />
    </BrowserRouter>
  );

  expect(screen.getByRole('link')).toHaveAttribute('href', '/articles');
});

테스트할 주요 컴포넌트는 다음과 같습니다.

// HomePage.js
import React from 'react';
import { Link } from 'react-router-dom';

const HomePage = () => {
  return (
    <>
      <h1>Welcome to React page</h1>
      <p>
        Click on <Link to='/articles'>Articles</Link> to see what is shared
        today
      </p>
    </>
  );
};

export default HomePage;

Link 컴포넌트는 라우터 컴포넌트 안에 넣을 수 있습니다.다음과 같은 경우:

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

크게 변경하지 않으려면 onClick() 메서드에서 아래 코드를 사용하십시오.

this.props.history.push('/');

언급URL : https://stackoverflow.com/questions/48640280/you-should-not-use-link-outside-a-router

반응형