Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 反应:按历史记录跟踪历史记录更改。推入公共组件_Javascript_Reactjs - Fatal编程技术网

Javascript 反应:按历史记录跟踪历史记录更改。推入公共组件

Javascript 反应:按历史记录跟踪历史记录更改。推入公共组件,javascript,reactjs,Javascript,Reactjs,我有一个布局组件,它包装了我的应用程序的其余部分。默认路由是一个带有多个按钮的页面,作为一个称为NavButton的小组件实现,它使用历史记录。按可转到新路由。然后在我的布局组件中,有两个按钮,但其中一个按钮应该根据当前导航到的路线而改变。因此,当我们在主页上时,按钮应显示“更改代码”,但在任何其他页面上,它应显示“返回”。我试过以下方法: Layout.tsx: interface ILayoutProps { children: ReactNode; } const Layout: R

我有一个布局组件,它包装了我的应用程序的其余部分。默认路由是一个带有多个按钮的页面,作为一个称为NavButton的小组件实现,它使用
历史记录。按
可转到新路由。然后在我的布局组件中,有两个按钮,但其中一个按钮应该根据当前导航到的路线而改变。因此,当我们在主页上时,按钮应显示“更改代码”,但在任何其他页面上,它应显示“返回”。我试过以下方法:

Layout.tsx:

interface ILayoutProps {
  children: ReactNode;
}

const Layout: React.FC<ILayoutProps> = ({ children }) => {
  const currentRoute = useLocation();

  useEffect(() => {
    console.log(currentRoute);
  }, [currentRoute]);

  const logout = () => {
    console.log('logout');
  };

  return (
    <div>
      <div>{children}</div>
      <Grid container spacing={2}>
        <Grid item xs={6}>
          {currentRoute.pathname === '/' ? (
            <NavButton displayName="Change Code" route="/change-code" variant="outlined" />
          ) : (
            <Button variant="outlined" color="primary" fullWidth>
              Back
            </Button>
          )}
        </Grid>
        ...
      </Grid>
    </div>
  );
};

export default Layout;
interface-ILayoutProps{
子节点:反应节点;
}
常量布局:React.FC=({children})=>{
const currentRoute=useLocation();
useffect(()=>{
console.log(currentRoute);
},[currentRoute]);
常量注销=()=>{
console.log(“注销”);
};
返回(
{儿童}
{currentRoute.pathname==='/'(
) : (
返回
)}
...
);
};
导出默认布局;
NavButton.tsx:

interface NavButtonProps {
  displayName: string;
  route: string;
  variant?: 'text' | 'outlined' | 'contained';
}

const NavButton: React.FC<NavButtonProps> = ({ displayName, route, variant = 'contained' }) => {
  const history = useHistory();

  const navigatePage = () => {
      history.push(route);
      // Also tried it like this:
      // setTimeout(() => history.push(route), 0);
  };

  return (
    <Button
      variant={variant}
      color="primary"
      onClick={() => navigatePage()}
      fullWidth
    >
      {displayName}
    </Button>
  );
};

export default NavButton;
界面导航按钮操作{
显示名称:字符串;
路径:字符串;
变体?:“文本”|“概述”|“包含”;
}
const NavButton:React.FC=({displayName,route,variant='contained'})=>{
const history=useHistory();
const navigatePage=()=>{
历史。推(路线);
//我也这样试过:
//setTimeout(()=>history.push(路由),0);
};
返回(
导航页面()}
全宽
>
{displayName}
);
};
导出默认导航按钮;

因此,在我的布局中,我试图通过
useLocation()
hook跟踪位置变化,但当按下按钮时,因此调用了
history.push(route)
,布局中的hook不会检测到它。我还尝试使用
useHistory()
hook并对其调用
listen()
方法,但问题相同。另外,我的路由器是BrowserRouter,不确定这是否有帮助。。。我在这里遗漏了什么?

所以问题是我的应用程序组件定义如下:

<Layout>
    <Routes />
</Layout>
<BrowserRouter>
    <Switch>
        <Route ...>
        ....
    </Switch>
</BrowserRouter>

我的路线是这样的:

<Layout>
    <Routes />
</Layout>
<BrowserRouter>
    <Switch>
        <Route ...>
        ....
    </Switch>
</BrowserRouter>

....
我的布局中的
useLocation()
挂钩不起作用,因为它不是我的BrowserRouter的子项。将其更改为那样可以使代码正常工作


我唯一觉得奇怪的是,在我的应用程序中,我没有因为无效的钩子调用而得到错误,但在沙盒中我得到了。也许我需要升级我的React软件包…

我将您的代码复制/粘贴到codesandbox中,在导航时,我会在
布局中看到位置日志。我还在那里实现了历史侦听器,可以看到
位置
和导航方法注销。你能为你的代码创建一个运行中的代码沙盒来重现你所看到的问题吗?好吧,试着让它在沙盒上工作让我意识到问题是什么。我不断收到无效钩子调用的错误,因为我使用布局作为路由器的包装,而它实际上需要是路由器的子级。做了那个改变,我让它工作了。是的,那就行了。干杯。如果您尚未升级到更新版本的CRA/react脚本,则可以尝试手动添加。