React 和 antd:路由器不会重新渲染组件 [英] React and antd: Router doesn't re-render components

查看:67
本文介绍了React 和 antd:路由器不会重新渲染组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有登录和搜索页面的简单网页.我在顶部还有一个导航栏,可以在两者之间切换.基本的 App.js 如下所示:

const history = createBrowserHistory();功能应用(){返回 (<路由器历史={历史}><自定义布局><开关><BaseRouter/></开关></自定义布局></路由器>);}导出默认应用程序;

现在,BaseRouterCustomLayout 只是

const BaseRouter = () =>(<div><路由精确路径={"/list"} component={ItemsList}/><路由路径={/login"}组件={LoginForm}/>

);导出默认 BaseRouter;

const CustomLayout = ({children}) =>{返回(<><导航栏/>{孩子们}</>);}导出默认自定义布局;

现在,导航栏看起来像这样

从反应"导入反应;从'antd'导入{Menu};从react-router-dom"导入{Link};const 导航栏 = () =>{返回 (<div><菜单模式=水平";主题={黑暗"}><Menu.Item key="list"><Link to={"/list>}>List</Link></Menu.Item><Menu.Item key={登录"}><Link to={"/login>登录</Link></Menu.Item></菜单>

);}导出默认导航栏

让组件保持简单:

const Login = () =>{返回 (<div>登录

);}导出默认登录const List = () =>{返回 (<div>列表

);}导出默认列表

现在的问题是,当我点击导航栏中的链接时,即使路由发生变化,React 也不会重新渲染组件.我已经在 SO 上看到了数百个答案,但我仍然无法弄清楚.
注意
避免刷新或重新加载页面对我来说很重要.
编辑
奇怪的是,当我将 Router 更改为 BrowserRotuer 时,它工作正常,但那时我无法使用自己的历史记录.

解决方案

为什么不使用 react-router-dom 包中的 BrowserRouter.

import { BrowserRouter as Router, Switch } from 'react-router-dom'功能应用(){返回 (<路由器><自定义布局><开关><BaseRouter/></开关></自定义布局></路由器>);}导出默认应用程序;

import { Route } from 'react-router-dom'const BaseRouter = () =>(<div><路由精确路径=/list";组件={ItemsList}/><路由路径="/login";组件={登录表单}/>

);导出默认 BaseRouter;

从反应"导入反应;从'antd'导入{Menu};从react-router-dom"导入{Link};const 导航栏 = () =>{返回 (<div><菜单模式=水平";主题={黑暗"}><Menu.Item key={list"}><链接到=/list">列表</Link></Menu.Item><Menu.Item key={登录"}><链接到=/登录">登录</链接></Menu.Item></菜单>

);}导出默认导航栏

那么如果你想使用 history:-

import { useHistory } from 'react-router-dom'const testFunctionComponent = () =>{const 历史 = useHistory()const handleClick = (urlPath) =>{//你可以做history.push(urlPath)//去任何地方}返回 (<><button onClick={() =>handleClick('/anypath')}>点击我!<button></>)}

I have a simple web page with login and search pages. I also have a navbar at the top to allow for switching between the two. The basic App.js looks as follows:

const history = createBrowserHistory();

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

export default App;

Now, the BaseRouter and CustomLayout are just

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

export default BaseRouter;

and

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

export default CustomLayout;

Now, the navbar looks like this

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

Let's keep components simple:

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

export default Login

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

export default List

Now the problem is that when I click on links in the navbar, React doesn't re-render components even though the route changes. I've seen hundreds of answers on SO but I still can't figure it out.
NOTE
It is important for me to avoid refreshing or reloading the page.
EDIT
Strangely enough, when I change Router to BrowserRotuer it works fine, but I can't use my own history then.

解决方案

why don't you use BrowserRouter from react-router-dom package.

import { BrowserRouter as Router, Switch } from 'react-router-dom'

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

export default App;

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

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

export default BaseRouter;

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

then if you want to use 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>
    </>
  )
}

这篇关于React 和 antd:路由器不会重新渲染组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆