React中不同路由对应非父子组件之间传递数据的方案咨询
React跨路由非嵌套组件状态共享最佳实践
根据你的场景(3个平级路由组件、数据从Register单向流向另外两个组件、无强关联跳转逻辑),推荐按项目复杂度从以下方案中选择:
方案1:状态提升到公共父组件(无额外依赖,轻量项目首选)
这是最符合React原生设计的最佳实践,三个路由的公共父组件是App,直接把Register里的表单状态提升到App层维护即可:
- 将原来存在Register state里的表单数据、修改方法移到App组件中
- 通过Route的render属性(React Router v5)或element属性(React Router v6)将状态和修改方法传递给三个子路由组件
改造示例代码如下:
// App组件改造示例(React Router v5 函数组件写法) import { useState } from 'react' const App = () => { // 初始化表单状态,也可从sessionStorage读取实现刷新不丢失 const [userFormData, setUserFormData] = useState({ username: "", password: "", authCode: "", email: "", country: "", countryCode: "", onlyPhone: "", }) return ( <IntlProvider locale={locale} messages={lang}> <BrowserRouter> <div className="h-100"> <Route path="/" exact render={props => <Register {...props} userFormData={userFormData} setUserFormData={setUserFormData} />} /> <Route path="/mfa" render={props => <MFA {...props} userFormData={userFormData} />} /> <Route path="/verify" render={props => <Verify {...props} userFormData={userFormData} />} /> </div> </BrowserRouter> </IntlProvider> ) }
之后Register组件内直接用props传入的userFormData和setUserFormData操作数据即可,原组件内的本地state可以直接移除。如果需要页面刷新后数据不丢失,只需要在状态更新时同步写入sessionStorage,App初始化时从sessionStorage读取初始值即可。
方案2:React Router 路由状态传参(适合一次性跳转传参场景)
如果你的场景只有Register跳转到MFA/Verify时才需要传数据,没有后续跨页面同步修改的需求,可以直接用React Router自带的跳转state传参,无需修改上层组件:
// Register组件内跳转时携带数据(React Router v5 类组件写法) this.props.history.push({ pathname: '/mfa', state: { userFormData: this.state } })
在目标组件内直接获取数据:
// MFA/Verify组件内取数 const userData = this.props.location.state?.userFormData
这个方案的缺点是用户直接刷新目标路由页面时,传递的state会丢失,仅适合跳转逻辑固定的一次性传参场景。
方案3:全局状态管理(适合中大型项目)
如果你的应用后续还有大量跨组件共享状态的需求,可以引入轻量全局状态管理库(如Zustand、Jotai)或者Redux、MobX等成熟方案,把表单数据存在全局store中,三个路由组件可以直接读写store数据,天生支持跨路由共享,也可以通过配套的持久化插件解决刷新丢数据的问题。
不推荐使用自定义事件总线、props层层透传等方案,这类方案维护成本极高,不属于React最佳实践范畴
内容的提问来源于stack exchange,提问作者Eric Mitjans
相关产品推荐
相关产品推荐

