React路由间传参是否常见?当前props传参方式是否为最佳实践?
问题描述
我负责的项目未使用状态管理库,页面头部设有按钮,需在主体路由内监听按钮点击事件,因此采用props层层传递参数的方式(代码如下)。该方式可正常运行,但同事表示这种传参方式并不常见,也不属于最佳实践,请问此说法是否正确?
Body组件代码
export default function Body({ version }) { const [selectedHeaderButton, setSelectedHeaderButton] = useState({ index: undefined, label: "Select Vehicle Plan", }); return ( <div> <HeaderBar open={open} drawerWidth={drawerWidth} handleDrawerOpen={handleDrawerOpen}> <Header selectedHeaderButton={selectedHeaderButton} setSelectedHeaderButton={setSelectedHeaderButton} version={version} /> </HeaderBar> <MainRoutes selectedHeaderButton={selectedHeaderButton} setSelectedHeaderButton={setSelectedHeaderButton} /> </div> ); }
MainRoutes组件代码
export default function MainRoutes({ selectedHeaderButton, setSelectedHeaderButton }) { return ( <main> <div> <Routes> <Route exact element={ <Rpo selectedHeaderButton={selectedHeaderButton} setSelectedHeaderButton={setSelectedHeaderButton} ></Rpo> } path="/" /> {/* <Route component={Page404} /> */} </Routes> </div> </main> ); }
回答
你同事的说法是正确的,这种多层props传递的做法确实不属于React开发的最佳实践,核心问题如下:
- 维护成本高:这是典型的「props钻取(Props Drilling)」场景,如果后续组件层级加深(比如
Rpo还有子组件需要该状态),你得持续逐层传递状态和修改函数;一旦要调整状态结构,所有中间组件都得同步修改,非常繁琐。 - 组件耦合性过强:中间组件(比如
MainRoutes)本身并不依赖selectedHeaderButton状态,只是充当传递的「中转站」,这会让这些组件和状态强绑定,大幅降低组件的复用性——比如MainRoutes要适配其他页面场景时,还得处理这些无关的props。 - 可读性差:多层传递后,新开发者很难快速定位状态的源头和流向,排查问题时需要逐层追溯,增加了理解成本。
无需全局状态库的替代方案
如果暂时不想引入Redux、Zustand这类状态管理库,用React内置特性就能解决问题:
1. Context API
将状态和修改函数放入Context,需要用到的组件直接从Context中获取,跳过逐层传递的步骤:
// 1. 创建Context const HeaderButtonContext = React.createContext(); // 2. 在Body组件中提供Context export default function Body({ version }) { const [selectedHeaderButton, setSelectedHeaderButton] = useState({ index: undefined, label: "Select Vehicle Plan", }); return ( <HeaderButtonContext.Provider value={{ selectedHeaderButton, setSelectedHeaderButton }} > <HeaderBar open={open} drawerWidth={drawerWidth} handleDrawerOpen={handleDrawerOpen}> <Header version={version} /> </HeaderBar> <MainRoutes /> </HeaderButtonContext.Provider> ); } // 3. 在Header组件中使用Context function Header({ version }) { const { selectedHeaderButton, setSelectedHeaderButton } = React.useContext(HeaderButtonContext); // 按钮点击等逻辑直接使用即可 } // 4. 在Rpo组件中使用Context function Rpo() { const { selectedHeaderButton, setSelectedHeaderButton } = React.useContext(HeaderButtonContext); // 监听状态变化的逻辑直接使用即可 }
2. 组件组合(Component Composition)
利用React的组件嵌套特性,让状态直接传递给最终需要的组件,中间组件只负责渲染:
// 调整Body组件 export default function Body({ version }) { const [selectedHeaderButton, setSelectedHeaderButton] = useState({ index: undefined, label: "Select Vehicle Plan", }); return ( <div> <HeaderBar open={open} drawerWidth={drawerWidth} handleDrawerOpen={handleDrawerOpen}> <Header selectedHeaderButton={selectedHeaderButton} setSelectedHeaderButton={setSelectedHeaderButton} version={version} /> </HeaderBar> <MainRoutes> <Rpo selectedHeaderButton={selectedHeaderButton} setSelectedHeaderButton={setSelectedHeaderButton} /> </MainRoutes> </div> ); } // 调整MainRoutes组件 export default function MainRoutes({ children }) { return ( <main> <div> <Routes> <Route exact element={children} path="/" /> </Routes> </div> </main> ); }
总结
你的写法能正常运行,但长期维护会埋下不少隐患。如果项目规模较小,用Context API或组件组合就能解决问题;如果后续项目会扩展,再考虑引入专门的状态管理库会更合理。
内容的提问来源于stack exchange,提问作者Lior Yitzhak
相关产品推荐
相关产品推荐

