React路由切换分类筛选仅返回首页生效问题排查
问题根因
- 核心bug在
ButtonMenu的生命周期设计:/men和/women路由复用了同一个ButtonMenu组件,React Router切换同组件路由时不会销毁重建组件,只会更新传入的props。你把路由路径对应的筛选逻辑写在了componentDidMount钩子里,这个钩子仅在组件首次挂载时触发。从男士分类页直接跳女士分类页时,组件没有经历卸载-重新挂载的流程,componentDidMount不会执行,筛选逻辑自然不会跑,页面就保留了之前男士分类的商品数据。只有先返回首页(首页渲染的是Home组件,ButtonMenu会被卸载,再进入女士分类页时组件重新挂载,componentDidMount才会触发),筛选逻辑才会正常生效。 - 附带语法错误:
App.js里的路由标签写乱了,/women对应的Route被写到了<Routes>标签外部,还有标签截断的问题,本身路由结构就不符合React Router的语法要求。
修复步骤
1. 修正App.js的路由结构
把所有Route标签放到<Routes>内部,补全被截断的标签,修正后核心代码如下:
class App extends React.Component { state= { cart: [] } updateCart = (cartItem) => { this.setState({cart: [...this.state.cart, cartItem]}) } removeFromCart = (id) => { this.setState({cart: this.state.cart.filter(i => i.id !== id)}) } render() { return ( <div className="App"> <Router> <Navigation/> <Routes> <Route path="/" element={<Home />} /> <Route path="/men" element={<ButtonMenu updateCart={this.updateCart} path={'men'}/>} /> <Route path="/women" element={<ButtonMenu updateCart={this.updateCart} path={'women'}/>} /> </Routes> <FooterNav/> </Router> </div> ) } }
2. 给ButtonMenu添加props变化监听
在ButtonMenu类中新增componentDidUpdate生命周期方法,监听path props的变化,当路由切换导致path更新时,自动重新执行商品筛选逻辑,新增代码如下:
// 放到ButtonMenu类里,和componentDidMount、getCategory同级 componentDidUpdate(prevProps) { // 对比前后path值,只有path真的变了才重新筛选,避免不必要的render if (prevProps.path !== this.props.path) { const currentPath = this.props.path if (currentPath === "all") { this.setState({ products: ProductList }); return } const filteredProducts = ProductList.filter((d) => d.category === currentPath); this.setState({ products: filteredProducts }); } }
可选优化:你现在把筛选后的商品列表存在组件state里属于冗余设计,完全可以直接根据当前选中的分类、路由path直接计算得到要展示的商品,不需要额外维护state,能从根源上避免状态和props不同步的问题。
内容的提问来源于stack exchange,提问作者madQuestions
相关产品推荐
相关产品推荐

