在 react-router v4 中对不同的路由路径使用相同的组件

Posted

技术标签:

【中文标题】在 react-router v4 中对不同的路由路径使用相同的组件【英文标题】:using same component for different route path in react-router v4 【发布时间】:2018-08-06 15:31:53 【问题描述】:

我正在尝试在我的反应应用程序中为添加/编辑表单提供单独的路由但相同的组件,如下所示:

<Switch>
        <Route exact path="/dashboard" component=Dashboard></Route>
        <Route exact path="/clients" component=Clients></Route>
        <Route exact path="/add-client" component=manageClient></Route>
        <Route exact path="/edit-client" component=manageClient></Route>        
        <Route component= NotFound  />        
</Switch>

现在在 manageClient 组件中,我解析查询参数(我在编辑路由中传递了一个带有客户端 ID 的查询字符串),我根据传递的查询参数有条件地呈现。

问题在于这不会再次重新安装整个组件。假设打开了一个编辑页面,并且用户单击添加组件,URL 会更改,但该组件不会重新加载,因此仍保留在编辑页面上。

有没有办法解决这个问题?

【问题讨论】:

manageClientrender() 方法的根DOM 元素中,尝试添加一个key,它的值取决于你给它的任何查询字符串。例如,尝试将其设置为 key="add" 用于 /add-client 和 key="edit" 用于 /edit-client。 (实际上我不知道这是否可行,这就是为什么我没有将其作为答案提交) 【参考方案1】:

为每条路由使用不同的key 应该会强制组件重新构建:

    <Route 
      key="add-client"
      exact path="/add-client"
      component=manageClient 
    />

    <Route 
      key="edit-client"
      exact path="/edit-client"
      component=manageClient 
    />

【讨论】:

是否可以从组件本身捕获键/路径? 有可能。您可以通过this.props.route.key 从组件中获取路由道具 这对我有用,直到我有一个动态路由(在路由中有一个 ID 属性,例如 /blog/post/:id)...密钥对于 URL 和任何 ID 都是唯一的,但在两个之间导航ID 映射到相同的路由和键​​两次,在映射到同一路由器条目的两条路由之间导航时无法重新呈现路由...例如在/blog/post/1/blog/post/2 之间导航也不会重新渲染... 为了澄清更多,“关键”是在反应协调中触发差异。仅供参考github.com/ReactTraining/react-router/issues/5972 和 reactjs.org/docs/reconciliation.html【参考方案2】:

一种解决方案是使用组件内联函数,每次都会渲染一个新组件,但这不是一个好主意。

像这样:

<Route exact path="/add-client" component=props => <ManageClient ...props />></Route>
<Route exact path="/edit-client" component=props => <ManageClient ...props />></Route> 

更好的解决方案是,在ManageClient 组件中使用componentWillReceiveProps 生命周期方法。想法是每当我们为两条路由渲染相同的组件并在它们之间切换时,react 不会卸载组件,它基本上只会更新组件。因此,如果您正在进行任何 api 调用或需要一些数据,请在此方法中执行所有路由更改。

要检查,请使用此代码并查看它会在路线更改时被调用。

componentWillReceiveProps(nextProps)
   console.log('route chnaged')

注意:只有在路由发生变化时才放条件并调用api。

【讨论】:

我相信这是更好的答案。建议使用 componentWillReceiveProps 作为进行 API 调用的位置是我所需要的,而无需卸载/安装相同的组件。 componentWillReceiveProps 从 React 16.3 开始已被弃用【参考方案3】:
<Route exact path=["/add-client", "/edit-client"]>
  <manageClient />
</Route>

参考

版本 5.2.0

https://reacttraining.com/react-router/web/api/Route/path-string-string

【讨论】:

【参考方案4】:

我的问题是我们在中间使用了 common 路径,这导致动态路径无法正常工作

      <Switch>
        <Route key="Home" path="/home" component=Home />
        <Route key="PolicyPlan-create"  path="/PolicyPlan/create" component=PolicyPlanCreatePage />
        /* <Route key="PolicyPlan-list" path="/PolicyPlan" component=PolicyPlanListPage /> */
        <Route key="PolicyPlan-list" path="/PolicyPlan/list" component=PolicyPlanListPage />            
        <Route key="PolicyPlan-edit"  path="/PolicyPlan/edit/:id" component=PolicyPlanCreatePage />   
        <Route key="cardDesign" path="/cardDesign" component=cardDesign />
        <Route key="Admin-create" path="/admin/create" component=RegisterPage />
      </Switch>

所以不要像注释的那样使用路径,现在代码可以工作了

.................
          this.props.history.push("/PolicyPlan/edit/" + row.PolicyPlanId);
.............    

【讨论】:

【参考方案5】:

您可以简单地在单个路由标记中提供一组路径,如下所示 -

<Route exact path=["/add-client", "/edit-client"] component=manageClient></Route>

【讨论】:

以上是关于在 react-router v4 中对不同的路由路径使用相同的组件的主要内容,如果未能解决你的问题,请参考以下文章

react-router v4 使用 history 控制路由跳转

在 react-router v4 的嵌套路由中看到空白页

浅入浅出 react-router v4 实现嵌套路由

如何使用 react-router v4 检测路由变化?

React-router v4教程

在 react-router v4 中将自定义道具传递给路由器组件