React Router v4跨组件传递props未生效,求正确实现方法
问题根因
- 路由匹配规则错误:根路由配置了
exact path="/"指向Login组件,当你跳转到/dashboard路径时,路径不匹配/的精确规则,Login组件直接被卸载,写在Login内部的/dashboard路由自然不会被执行,页面无内容渲染。 - 传递的Props命名不匹配:Login组件路由中给Dashboard传的属性名为
selected,但Dashboard组件中接收的属性名为selectedLanguage,名称不一致导致读取不到对应配置。
修复方案
推荐将共享状态提升到App父组件统一管理,这样两个路由页面都可以拿到共享数据,不会因为页面跳转丢失状态:
1. 修改根路由配置(index.js)
import React from 'react' import ReactDOM from 'react-dom' import './index.css' import Login from './components/Login' import Dashboard from './components/Dashboard' import Nav from './components/Nav' import {BrowserRouter as Router, Route } from 'react-router-dom' import { fetchLanguageRepos } from './utils/api' class App extends React.Component { constructor(props) { super(props) this.state = { selectedLanguage: 'EU', repos: null, error: null, } this.updateLanguage = this.updateLanguage.bind(this) } componentDidMount () { this.updateLanguage(this.state.selectedLanguage) } updateLanguage (selectedLanguage) { this.setState({ selectedLanguage, error: null }) fetchLanguageRepos(selectedLanguage) .then((repos) => this.setState({ repos, error: null, })) .catch((error) => { console.warn('Error fetching repos: ', error) this.setState({ error: 'There was an error fetching the repositories.' }) }) } render() { const { selectedLanguage, repos, error } = this.state return ( <Router> <div className='container'> <Nav /> <Route exact path='/' render={(props) => ( <Login {...props} selectedLanguage={selectedLanguage} repos={repos} error={error} updateLanguage={this.updateLanguage} /> )} /> <Route path='/dashboard' render={(props) => ( <Dashboard {...props} repos={repos} selectedLanguage={selectedLanguage} /> )} /> </div> </Router> ) } } ReactDOM.render( <App />, document.getElementById('app') )
2. 简化Login组件,移除内部冗余的路由和状态逻辑
删除Login组件内部的state定义、updateLanguage方法、以及Dashboard路由声明,直接从props接收需要的参数即可。
3. 可选优化Dashboard逻辑
Dashboard组件已经可以直接从props拿到repos和selectedLanguage,如果没有特殊需求不需要再把props存入内部state,避免props更新时state不同步的问题。
如果不想提升状态,临时修复可以只去掉根路由的exact修饰,这样访问/dashboard时Login组件也会渲染,内部的路由就会生效,但是Login页面的内容会和Dashboard同时展示,不推荐长期使用。
内容的提问来源于stack exchange,提问作者Julen Clarke
相关产品推荐
相关产品推荐

