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
。
我想通过单击它们两个内部的按钮在Header
和Footer
之间切换组件。
每次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
时不起作用。
我试过了,就是不行,useCallback
,useMemo
或者useEffect
也不行
如何/在哪里使用 AppWrapper
?我尝试使用 index.js 而不是 <App/>
但它给出了错误 - 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不能访问的问题