如何通过React Router的Link向类组件传递props或state?
解决React Router向类组件传递参数/state的问题
首先需要将BoardHome改为类组件,同时修正Board组件获取路由参数和state的方式,以下是完整解决方案:
1. 改造BoardHome为类组件
import React from 'react'; import { Link, Routes, Route } from 'react-router-dom'; import Board from './Board'; interface BoardHomeProps { id: number; title: string; } export default class BoardHome extends React.Component<BoardHomeProps> { componentDidMount() { console.log(this.props); // props可正常获取 } render() { const { id, title } = this.props; return ( <div className="board-home"> <Link className="board-link" to={{ pathname: `/board/${id}`, state: { id } }} > <div className="board-fade"> <h2 className="board-title">{title}</h2> </div> </Link> <Routes> <Route path="/board/:id" element={<Board />} /> </Routes> </div> ); } }
2. 方案一:通过中转组件传递路由信息给Board
在Route的element中用函数组件作为中转,获取路由参数和state后传递给Board类组件:
// 修改BoardHome中的Route部分 <Routes> <Route path="/board/:id" element={<BoardWrapper />} /> </Routes> // 新增中转用的函数组件(仅做参数传递,不违反类组件要求) const BoardWrapper = () => { const params = useParams<{ id: string }>(); const location = useLocation(); return <Board id={parseInt(params.id)} routeState={location.state} />; };
然后修改Board组件的props接口与state初始化逻辑:
import React from 'react'; import './board.scss'; import '../../index.css'; interface BoardProps { id: number; routeState?: { id: number }; } interface BoardState { id: number; } export default class Board extends React.Component<BoardProps, BoardState> { constructor(props: BoardProps) { super(props); // 初始化state,可选择从URL参数或路由state取值 this.state = { id: props.id }; } render() { console.log('props:', this.props); console.log('state:', this.state); return ( <div className="board-header"> <h1 className="board-h1">{this.state.id}</h1> </div> ); } }
3. 方案二:自定义withRouter高阶组件
如果不想用中转组件,可以自定义withRouter高阶组件,让Board类组件直接获取路由相关信息:
// 新建withRouter.tsx import React from 'react'; import { useParams, useLocation, useNavigate, Params, Location, NavigateFunction } from 'react-router-dom'; interface WithRouterProps { params: Params<string>; location: Location; navigate: NavigateFunction; } export function withRouter<T extends {}>(Component: React.ComponentType<T & WithRouterProps>) { return (props: Omit<T, keyof WithRouterProps>) => { const params = useParams(); const location = useLocation(); const navigate = useNavigate(); return <Component {...(props as T)} params={params} location={location} navigate={navigate} />; }; }
修改Board组件并使用高阶组件包装:
import React from 'react'; import './board.scss'; import '../../index.css'; import { withRouter } from './withRouter'; interface BoardProps { params: { id: string }; location: { state: { id: number } }; } interface BoardState { id: number; } class Board extends React.Component<BoardProps, BoardState> { constructor(props: BoardProps) { super(props); // 从路由参数或state中初始化id this.state = { id: parseInt(this.props.params.id) || this.props.location.state?.id || 0 }; } render() { console.log('路由参数:', this.props.params); console.log('路由state:', this.props.location.state); console.log('state:', this.state); return ( <div className="board-header"> <h1 className="board-h1">{this.state.id}</h1> </div> ); } } // 用withRouter包装组件,注入路由相关props export default withRouter(Board);
关键注意事项
- 原
Board组件未初始化state,导致this.state为null,必须在constructor中完成state初始化 - React Router v6移除了官方
withRouter高阶组件,需自定义或通过中转组件传递路由信息 - 路由
state仅在通过Link/navigate跳转时携带,页面刷新后会丢失,若需持久化参数建议使用URL参数
内容的提问来源于stack exchange,提问作者user18867426
相关产品推荐
相关产品推荐

