ReactRouter与create-react-app:如何按ID渲染子组件并配置编辑路由?
解决React Router导航到编辑视图的问题
看起来你遇到的核心问题是路由配置错误+组件状态与路由逻辑冲突,咱们一步步来解决:
1. 先修正路由路径的低级错误
你当前路由里的path="dashboard/:id"少了开头的斜杠,React Router会把它当成相对路径处理,导致无法正确匹配/dashboard/xxx这样的URL。先把index.js里的路由改成这样:
ReactDOM.render( <Router> <div> <Route exact path="/" component={App}/> {/* 去掉/dashboard路由的exact,这样它能匹配所有/dashboard开头的子路径 */} <Route path="/dashboard" component={App}/> {/* 修正路径,加上开头的斜杠 */} <Route path="/dashboard/:id" component={Editing}/> <Route exact path="/about" component={About}/> </div> </Router>, document.getElementById('root') );
2. 统一用路由驱动视图(替代组件内部state)
你现在同时用ItemContainer的view状态和路由来控制编辑视图的显示,这就导致了冲突——路由跳转到/dashboard/:id了,但组件还在依赖自身state判断是否渲染编辑界面。咱们把逻辑改成完全由路由主导:
步骤A:调整App组件,添加嵌套路由
把原来App里直接渲染ItemContainer的逻辑,改成根据子路由渲染不同组件。这样App作为/dashboard的容器,负责管理items、user这些全局状态,然后把需要的props传递给子组件:
// 在App组件里引入Route import { Route } from 'react-router-dom'; import ItemContainer from './components/ItemContainer.js'; import Editing from './components/Editing.js'; class App extends React.Component { // 你的原有state和逻辑保持不变 render() { return ( <div className='container'> {/* 当访问/dashboard时,渲染列表视图 */} <Route exact path="/dashboard" render={() => ( <ItemContainer user={this.state.user} items={this.state.items} userProfile={this.state.userProfile} /> )} /> {/* 当访问/dashboard/:id时,渲染编辑视图 */} <Route path="/dashboard/:id" render={(routeProps) => { // 从路由参数里拿到item id,匹配对应的item const targetItem = this.state.items.find(item => item.id === routeProps.match.params.id); return ( <Editing item={targetItem} uid={this.state.user.uid} // 提供返回列表的方法,比如点击取消/保存后跳回dashboard viewList={() => routeProps.history.push('/dashboard')} /> ); }} /> </div> ); } }
步骤B:简化ItemContainer组件
既然路由已经负责视图切换了,ItemContainer里的view状态就不需要了,直接渲染列表即可:
// ItemContainer.js render() { return ( this.props.items.map(item => ( <li key={item.id}> <Item item={item} user={this.props.user} /> </li> )) ); }
步骤C:简化Item组件的编辑按钮
原来的按钮同时绑定了onClick和Link,现在只需要保留Link跳转即可,不需要再触发组件内部的state改变:
// Item.js <div> <h3> {this.props.item.appName} </h3> <Link to={`/dashboard/${this.props.item.id}`}> <button>Edit</button> </Link> </div>
3. 可选:用Switch确保路由唯一匹配
如果担心多个路由同时匹配的问题,可以在最外层路由里用Switch组件,它会只渲染第一个匹配的路由:
import { Switch } from 'react-router-dom'; ReactDOM.render( <Router> <Switch> <Route exact path="/" component={App}/> <Route path="/dashboard/:id" component={App}/> <Route path="/dashboard" component={App}/> <Route exact path="/about" component={About}/> </Switch> </Router>, document.getElementById('root') );
这样修改后,点击编辑按钮就会正确跳转到/dashboard/xxx,App组件会根据路由参数找到对应的item并渲染Editing视图,完全由路由来控制页面状态,就不会出现路径无效的问题了。
内容的提问来源于stack exchange,提问作者Tapio
相关产品推荐
相关产品推荐

