React 및 antd : 라우터는 구성 요소를 다시 렌더링하지 않습니다.

Nov 13 2020

로그인 및 검색 페이지가있는 간단한 웹 페이지가 있습니다. 또한 상단에 탐색 바가있어 둘 사이를 전환 할 수 있습니다. 기본 App.js모양은 다음과 같습니다.

const history = createBrowserHistory();

function App() {
    return (
        <Router history={history}>
            <CustomLayout>
                <Switch>
                    <BaseRouter/>
                </Switch>
            </CustomLayout>
        </Router>
    );
}

export default App;

자, BaseRouter그리고 CustomLayout단지

const BaseRouter = () => (
    <div>
        <Route exact path={"/list"} component={ItemsList}/>
        <Route path={"/login"} component={LoginForm}/>
    </div>
);

export default BaseRouter;

const CustomLayout = ({children}) => {
    return(
        <>
        <Navbar/>
        {children}
        </>
    );
}

export default CustomLayout;

이제 navbar는 다음과 같습니다.

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

 const Navbar = () => {
    return (
        <div>
            <Menu mode="horizontal" theme={"dark"}>
                <Menu.Item key="list">
                    <Link to={"/list"}>List</Link>
                </Menu.Item>
                <Menu.Item key={"login"}>
                    <Link to={"/login"}>Sign in</Link>
                </Menu.Item>
            </Menu>
        </div>
    );
}

export default Navbar

구성 요소를 단순하게 유지합시다.

const Login = () => {
    return (
        <div>
            login
        </div>
    );
}

export default Login

const List = () => {
    return (
        <div>
            list
        </div>
    );
}

export default List

이제 문제는 navbar에서 링크를 클릭하면 경로가 변경 되어도 React가 구성 요소를 다시 렌더링하지 않는다는 것입니다. 나는 수백 개의 답변을 보았지만 여전히 그것을 알아낼 수 없습니다.
참고
페이지를 새로 고치거나 다시로드하지 않는 것이 중요합니다. 이상하게도
편집 하면 제대로 작동하지만 내 자신의 역사를 사용할 수 없습니다.
RouterBrowserRotuer

답변

1 lala Nov 13 2020 at 13:51

왜 패키지 BrowserRouter에서 사용하지 react-router-dom않습니까.

  • App.js: - 사용 BrowserRouter에서react-router-dom
import { BrowserRouter as Router, Switch } from 'react-router-dom'

function App() {
  return (
    <Router>
      <CustomLayout>
        <Switch>
          <BaseRouter/>
        </Switch>
      </CustomLayout>
    </Router>
  );
}

export default App;
  • BaseRouter.js: - 수입 Route에서react-router-dom
import { Route } from 'react-router-dom'

const BaseRouter = () => (
  <div>
    <Route exact path="/list" component={ItemsList}/>
    <Route path="/login" component={LoginForm}/>
  </div>
);

export default BaseRouter;
  • Navbar.js:-
import React from "react";
import {Menu} from 'antd';
import {Link} from "react-router-dom";

const Navbar = () => {
  return (
    <div>
      <Menu mode="horizontal" theme={"dark"}>
        <Menu.Item key={"list"}>
          <Link to="/list">List</Link>
        </Menu.Item>
        <Menu.Item key={"login"}>
          <Link to="/login">Sign in</Link>
        </Menu.Item>
      </Menu>
    </div>
  );
}

export default Navbar

다음을 사용하려면 history:-

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

const testFunctionComponent = () => {
  const history = useHistory()
  
  const handleClick = (urlPath) => {
    // you can do
    history.push(urlPath) // to go anywhere 
  }

  return (
    <>
      <button onClick={() => handleClick('/anypath')}>Click Me!<button>
    </>
  )
}
GayatriDipali Nov 13 2020 at 12:27

이에 서 변경 BaseRouter:

const BaseRouter = () => (
    <div>
        <Route exact path={"/list"} component={ItemsList}/>
        <Route path={"/login"} component={LoginForm}/>
    </div>
);

export default BaseRouter;

이에 :

const BaseRouter = () => (
    <div>
        <Route exact path="/list" component={ItemsList}/>
        <Route path="/login" component={LoginForm}/>
    </div>
);

export default BaseRouter;
ThalesKenne Nov 13 2020 at 12:35

나는 당신이 스위치 안에 div를 가질 수 없다고 믿습니다. Route 구성 요소를 switch 문에 노출하지 않습니다.

따라서 Navbar가 변경하지만 스위치가 무엇을 해야할지 모르기 때문에 URL이 변경됩니다.

기본 라우터를 다음으로 변경하십시오.

const history = createBrowserHistory();

function App() {
    return (
        <Router history={history}>
            <CustomLayout>

                    <BaseRouter/>

            </CustomLayout>
        </Router>
    );
}

export default App;
const BaseRouter = () => (
    <Switch>
        <Route exact path={"/list"} component={ItemsList}/>
        <Route path={"/login"} component={LoginForm}/>
    </Switch>
);

export default BaseRouter;
PhilipRamirez Nov 13 2020 at 13:32

Router저수준이며 당신이 일을 관리하기를 기대합니다. BrowserRouter이미 HTML5 기록과 동기화됩니다. 원하는 경우 Router동기화를 직접 관리해야한다고 생각합니다 (예 : <Link onClick={() => history.push(href)}>)변경 감지 기록을 들어야합니다. react-router로 경로 변경 감지 참조)