react-router-dom `history`:无法读取未定义的属性“推送”

Posted

技术标签:

【中文标题】react-router-dom `history`:无法读取未定义的属性“推送”【英文标题】:react-router-dom `history`: Cannot read property 'push' of undefined 【发布时间】:2021-09-20 21:11:41 【问题描述】:

我的父组件中有App.js 一个Header 和一个Footer。 我想通过单击它们两个内部的按钮在HeaderFooter 之间切换组件。 每次pageIndex 更改时,我都想替换为其他组件。

我收到此错误Cannot read property 'push' of undefined 为什么我会收到此错误并且是干净且适当的乳清(使用我的defaultRouter()useMemo

 function App() 
      const [pageIndex, setPageIndex] = useState();
      const [searchResults, setSearchResults] = useState([]);

      const history = useHistory();

       useEffect(() => 
         console.log(pageIndex, 'App');
       , [pageIndex]);
    
    const defaultRouter = useMemo(() => 
     // Or -  `const DefaultRouter = useMemo(() =>` instead of `useEffect()`
    switch (pageIndex) 
      case 1:
        history.push( pathname: '/search', state: searchResults );
        break;
      case 2:
        history.push('/cart');
        break;
      default:
        history.push('/');
        break;
    
   , [pageIndex]);

      return (
        <div className='App'>
          <Header/>
          <Home />
          defaultRouter;  
          <Footer />  
          <BrowserRouter>
            <Route path='/'>
              <Home />
            </Route>
            <Route path='/search'>
              <Search
                searchResults=searchResults
                setItemsAmount=setItemsAmount
              />
            </Route>
            <Route path='/cart'>
              <Cart />
            </Route>
            <Route component=PageNotFound />
          </BrowserRouter>
          ;
        </div>
      );
    

编辑

正如 Shyam 在下面的回答中建议的那样,我将 App.js 更改为 useCallback useCallback 不起作用

  const defaultRouter = useCallback(() => 
    console.log(pageIndex, 'callBack');
    switch (pageIndex) 
      case 1:
        history.push( pathname: '/search', state: searchResults );
        break;
      case 2:
        history.push('/cart');
        break;
      default:
        history.push('/');
        break;
    
  , [pageIndex]);

谢谢

【问题讨论】:

【参考方案1】:

这是因为该组件中没有设置 react-router 上下文。 由于它是设置上下文的组件,因此您可以在子组件中使用 useHistory,但不能在该子组件中使用。

这是解决这个问题的一个非常基本的策略:

const AppWrapper = () => 
  return (
    <Router> // Set context
      <App /> // Now App has access to context
    </Router>
  )


const App = () => 
  let history = useHistory(); // Works!
...

// 在这个组件中渲染路由 然后确保直接使用“包装器”组件而不是 App。

在这里回答: https://***.com/a/58221867/1723410

function App() 
  return (
    <BrowserRouter>
       <AppChildren />
    </BrowserRouter>
  )
     

function AppChildren() 
      const [pageIndex, setPageIndex] = useState();
      const [searchResults, setSearchResults] = useState([]);

      const history = useHistory();

       useEffect(() => 
         console.log(pageIndex, 'App');
       , [pageIndex]);
    
    const defaultRouter = useMemo(() => 
     // Or -  `const DefaultRouter = useMemo(() =>` instead of `useEffect()`
    switch (pageIndex) 
      case 1:
        history.push( pathname: '/search', state: searchResults );
        break;
      case 2:
        history.push('/cart');
        break;
      default:
        history.push('/');
        break;
    
   , [pageIndex]);

      return (
        <div className='App'>
          <Header/>
          <Home />
          defaultRouter;  
          <Footer />  
          <>
            <Route path='/'>
              <Home />
            </Route>
            <Route path='/search'>
              <Search
                searchResults=searchResults
                setItemsAmount=setItemsAmount
              />
            </Route>
            <Route path='/cart'>
              <Cart />
            </Route>
            <Route component=PageNotFound />
          </>
        </div>
      );
 

【讨论】:

1) AppWrapper 是否应该在不同的 jsx 文件中并被导出? 2) 我现在的useCallback Header 组件中更新pageIndex 时不起作用。 我试过了,就是不行,useCallbackuseMemo或者useEffect也不行 如何/在哪里使用 AppWrapper ?我尝试使用 index.js 而不是 &lt;App/&gt; 但它给出了错误 - TypeError: Cannot read property 'location' of undefined 所以你的 BrowserRouter 必须在父组件中。我更新了上面的答案

以上是关于react-router-dom `history`:无法读取未定义的属性“推送”的主要内容,如果未能解决你的问题,请参考以下文章

react-router-dom - 链接和history.push之间的区别?

React-router-dom:History.push 连接路径并且不会重新路由应用程序

React 项目使用 React-router-dom 4.0 以上版本时使用 HashRouter 怎么控制 history

解决 react-router / react-router-dom v4 history不能访问的问题

我在哪里可以找到 react-router-dom Location、History 和 Match 的类型?

react-router-dom