React中点击按钮从类组件导航至函数式组件并传递数据的问题排查与解决
问题分析与解决方案
首先得指出你代码里的核心问题:你在按钮点击事件里写 <GoToTemplateList/> 只是创建了一个React元素,但并没有把它挂载到DOM中,所以组件内部的useNavigate逻辑根本不会执行,自然没法触发导航。
下面给你几种在类组件中使用React Router v6导航的可行方案:
方案1:自定义高阶组件(HOC)注入navigate
React Router v6移除了官方的withRouter高阶组件,我们可以自己写一个,把navigate函数注入到类组件的props里:
// 自定义HOC,用于给类组件提供navigate import { useNavigate } from 'react-router-dom'; const withNavigate = (Component) => { return (props) => { const navigate = useNavigate(); return <Component {...props} navigate={navigate} />; }; }; // 改造你的Dept类组件 class Dept extends Component { constructor(props) { super(props); // 注意这里要调用super(props),你之前的代码漏了 } render() { return ( <> <div className="container"> <Button onClick={() => { // 调用props里的navigate,同时通过state传递数据 this.props.navigate('/office', { replace: true, state: { deptName: '技术部', deptId: 101 } // 这里放你要传递的数据 }); }}> 跳转到Office组件 </Button> </div> </> ); } } // 导出被HOC包装后的组件 export default withNavigate(Dept);
然后在Office函数式组件中接收传递的数据:
import { useLocation } from 'react-router-dom'; export default function Office(props) { const location = useLocation(); // 拿到从Dept传递过来的数据 const { deptName, deptId } = location.state || {}; console.log('接收的数据:', deptName, deptId); // 你的业务逻辑代码 return <div>Office组件</div>; }
方案2:通过Context共享navigate函数
如果你的项目已经在用React Context,可以把navigate放到Context中,让类组件可以直接访问:
// 第一步:创建导航Context import { createContext, useContext, useNavigate } from 'react-router-dom'; const NavigateContext = createContext(); // 第二步:创建Context提供者组件 export const NavigateProvider = ({ children }) => { const navigate = useNavigate(); return ( <NavigateContext.Provider value={navigate}> {children} </NavigateContext.Provider> ); }; // 第三步:在根组件中包裹NavigateProvider(比如App.js) import { BrowserRouter, Routes, Route } from 'react-router-dom'; import { NavigateProvider } from './NavigateContext'; import Dept from './Dept'; import Office from './Office'; function App() { return ( <BrowserRouter> <NavigateProvider> <Routes> <Route path="/dept" element={<Dept />} /> <Route path="/office" element={<Office />} /> </Routes> </NavigateProvider> </BrowserRouter> ); } // 第四步:在Dept类组件中使用Context import { NavigateContext } from './NavigateContext'; class Dept extends Component { // 声明要使用的Context static contextType = NavigateContext; render() { return ( <> <div className="container"> <Button onClick={() => { // 通过this.context获取navigate函数 this.context('/office', { replace: true, state: { data: '自定义数据' } }); }}> 跳转到Office组件 </Button> </div> </> ); } }
方案3:从父函数式组件传递navigate
如果Dept的父组件是函数式组件,那可以直接在父组件中获取navigate,再作为props传给Dept:
// 父函数式组件 import { useNavigate } from 'react-router-dom'; import Dept from './Dept'; function ParentComponent() { const navigate = useNavigate(); return <Dept navigate={navigate} />; } // 然后在Dept组件中直接使用this.props.navigate,用法和方案1一致
内容的提问来源于stack exchange,提问作者sagar patil
相关产品推荐
相关产品推荐

