You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:52:35