如何使用嵌套路由向页面添加内容而不使用react-router-v4删除以前路由的内容?

问题描述 投票:5回答:4

我正在使用react-router-v4官方文档中提供的侧边栏示例作为灵感https://reacttraining.com/react-router/web/example/sidebar

1-因此,我的应用程序的初始URL将是:localhost:3000/search-page/Lists

2-我有一个可点击的链接列表,点击时会在侧边栏上显示点击的数据,当这种情况发生时,URL会更新:localhost:3000/search-page/Lists/itemList1selected

3-然后按“显示列表编号2”按钮显示新列表

4-当我点击“列表编号2”中的链接时,我的目标是使用嵌套路由。它会将它附加在从“列表编号1”中选择的项目下面...并同时更新URL:localhost:3000/search-page/Lists/itemList1selected/itemList2selected

这是我目前的代码:

class MyComponent extends Component {

  constructor(props) {
   super(props);
     this.state = {
      showListButtonPressed: true
     };
   this.showTheOtherList = this.ShowTheOtherList.bind(this);
  }

  showTheOtherList() {
   this.setState({
     showListButtonPressed: !this.state.showListButtonPressed
   });
  }

 render() {
   const dataList1 = dataFromDataBase
     .allItemsFromList1()
     .map(list1 => ({
       path: `${this.props.match.params.type}/${list1.id}`,
       mainList1: () => (
        <div>
          {`${list1.company}   ${list1.name}   ${list1.price}`}
        </div>
       ),
       sidebarList1: () => (
         <div>
           <h3>item List 1 selected</h3>
             {list1.company}
         </div>
       )
     }));

   const dataList2 = fakeFlightApiDataTesting
     .allItemsFromList2()
     .map(list2 => ({
       path: `${this.props.match.params.type}/${list2.id}`,
       mainList2: () => (
         <div>
           {`${list2.company} ${list2.name} ${list2.price}`}
         </div>
       ),
       sidebarList2: () => (
         <div>
           <h3>item List 2 selected</h3>
            {list2.company}
         </div>
       )
     }));

    return (
       <div style={{ display: 'flex' }}>
         <div style={{ width: '20%' }}>

           {dataList1.map(route => (
             <div>
               <Route
                 key={route.path}
                 path={`/search-page/${route.path}`}
                 exact={route.exact}
                 component={route.sidebarList1}
               />
             </div>
           ))}

           {dataList2.map(route => (
             <div>
               <Route
                 key={route.path}
                 path={`/search-page/${route.path}`}
                 exact={route.exact}
                 component={route.sidebarList2}
              />
             </div>
           ))}
         </div>
         <div>
           // Switch the lists when button is pressed
           {this.state.showListButtonPressed ? (
             <div>
               <ul>
                 {dataList1.map(route => (
                   <li key={route.path}>
                     <Link to={`/search-page/${route.path}`}>
                       {route.mainList1()}
                     </Link>
                   </li>
                 ))}
               </ul>
                <button onClick={this.showTheOtherList}> 
                  Switch Lists
                </button>
             </div>
           ) : (
             <div>
               <ul>
                 {dataList2.map(route => (
                   <li key={route.path}>
                     <Link to={`/search-page/${route.path}`}>
                       {route.mainList2()}
                     </Link>
                   </li>
                 ))}
               </ul>

               <button onClick={this.showTheOtherList}> 
                 switch Lists 
               </button>
             </div>
           )}
         </div>
       </div>
     );
   }
 }

这里有一些截图可以有更好的主意:

What I already done and coded This is what I'm trying to achieve

javascript reactjs react-router-v4 react-router-dom
4个回答
5
投票

困难的部分是因为你使用了2个路径参数,它的功能与它们使用的例子完全不同。假设您有“n”list1选项和“m”list2选项。这意味着你将n x m总路线。要使它像这样工作,您需要创建一个list2路由与每个list1选项相结合。然后list2的path键看起来像${this.props.match.params.type}/${list1.id}/${list2.id}。我认为这也可以通过为list2 ${this.props.match.url}/${list2.id}创建路径来实现,但它需要始终首先选择list1。

这是一个非常棘手的案例,但我希望有所帮助


3
投票

您可以使用不同的方法来解决此问题:

  1. 从官方的React Router v4 recursive paths获得另一个灵感。

使用此模式,您可以创建深度嵌套的列表,深度超过2个级别。

  1. 检查侧边栏中是否已在第一级选择了1个项目,并为该案例渲染另一个<SidebarRoute />,将第二级选择项目作为道具。

我建议你(第3个选项)将选定的项目保持在状态,并在侧栏中相应地渲染。如果您没有义务通过电子邮件或其他方式发送链接,只需要渲染,此选项就可以正常运行。然后,您可以在您选择的商店中保存UI状态(redux,flux,您可以命名)。

第二种方法的基本示例(idlvl2是您要在侧边栏中显示的内容):https://codesandbox.io/s/o53pq1wvz


1
投票

这可能只是一个错字,但在您的渲染组件中,您忘记将路由器添加到最外层的div。必须在路由器组件内定义路由组件。


1
投票

在我看来,你可以使用搜索参数。

但是,如果您没有机会更改路径接收器组件的逻辑,则需要按照建议使用recursive paths路由。

关于搜索参数。所以不要添加localhost:3000/search-page/Lists/itemList1selected/itemList2selected,而是添加localhost:3000/search-page/Lists?item1=itemList1selected&item2=itemList2selected

您可以通过URLSearchParams提取值,请注意IE不支持它。

这种方法有3个优点。首先,它将始终呈现List,它将处理逻辑,不需要嵌套路由。其次,你可以添加几个项目,而不仅仅是两个。第三个url将处理所有逻辑,你可以共享链接并期望相同的结果。

© www.soinside.com 2019 - 2024. All rights reserved.