【问题标题】:Declaring routes using an array使用数组声明路由
【发布时间】:2016-08-06 16:09:24
【问题描述】:

我想将 React Router 的路由声明移动到单独的文件中,然后自动完成路由规范,如下所示:

// Central array for routes
const routes = [];

// Two routes in separate files
routes.push(<Route path="page1" component="Component1"/>);
routes.push(<Route path="page2" component="Component2"/>);

// Render the routes
<Router history={browserHistory}>
  {routes}
</Router>

虽然这可行,但我收到了警告,即迭代器的所有子节点,即路由,都应该有一个 key prop: Each child in an array or iterator should have a unique "key" prop. 但是在这种情况下真的需要密钥吗?据我了解,即使我使用的是数组,路由也只渲染一次并且不是动态的。

是否可以在 React 中做到这一点?

【问题讨论】:

    标签: javascript reactjs react-router


    【解决方案1】:

    因为您使用的是表达式(而不是硬编码/预配置的子项),并且因为该表达式被评估为一个数组,所以 React 认为这是一个具有动态子项的组件,因此它开始警告您信息。

    再想一想,这是有道理的。因为就 React 而言,没有什么能阻止您修改该数组并期望表达式解析为不同的数据集。因此它认为它是一个具有动态子组件的组件。

    【讨论】:

      【解决方案2】:

      据我了解,即使我使用的是数组,路由也只会渲染一次并且不是动态的。

      尽管&lt;Router&gt; 只会渲染一次,它仍然是一个 React 组件并且它不知道它会“只渲染一次”。组件需要准备好“重新渲染”并有效地执行此操作。

      为了确保组件高效渲染,它会要求提供这些“键”。


      您可以在此处停止阅读我的回复,但如果您想围绕它建立更多直觉,请继续阅读 :)

      想象一下,你目睹了一个小偷偷了一个老妇人的钱包......

      警察带你来识别阵容中的坏人。排队室外有8名嫌疑人。警官将前 6 名嫌疑人带入房间。由于房间容量问题,另外 2 人在外面等候。

      他们每个人都持有一个 ID 标签(key)。你仔细看看他们每个人,然后在一张纸上写下他们的 ID。您仍然需要见其他 2 名嫌疑人,但根据法律,排队室必须始终有 6 人。这意味着您刚才看到的 4 个将留在阵容室。

      因为您非常聪明,并且记下了您已经查看过的嫌疑人的 ID(查看 = 渲染),所以您可以跳过查看 ID 已经在您的列表中的嫌疑人。

      我知道这是一个奇怪的例子,但我希望它有所帮助:)

      如果您想了解更多详细信息,请从 React 文档开始:https://facebook.github.io/react/docs/reconciliation.html#list-wise-diff

      【讨论】:

      • 哈哈,谢谢你的故事! :D 我希望有一种方法可以告诉 React 它不应该关心密钥。或者换句话说:我不介意再次查看嫌疑人以找出之前在房间里的人。它可能会慢一些,但结果是一样的。
      【解决方案3】:

      如果您将道具发送到没有特定 ID 的子组件,您会看到此警告。

      所以基本上当你说运行一个循环并将参数传递给子组件时,你需要为 props 中的每个迭代指定 id。

      例如,

      const a=[
         {'id':1,'name':'x',age:'25'},
         {'id':2,'name':'y',age:'26'},
      ]
      

      父组件:-

        class Parent extends React.Component{
      
          constructor(){
            super();
            this.state={
               details=[
                 {'id':1,'name':'x',age:'25'},
                 {'id':2,'name':'y',age:'26'},
                ] 
             } 
          }
      
            _getDetails() {
                     return this.state.details.map((content)=>{
                           return (
                          <Child key={content.id} name={content.name} age={content.age}/>
                          );
                     });
               }
      }
      

      上面的 Child 是您将 props 传递到的组件。

      【讨论】:

      • 我明白为什么键是必要的,但我的问题更多是关于路由上下文中的动态子级。在我看来,给路由一个 ID 是没有意义的。
      【解决方案4】:

      一个简单的解决方案是使用Plain Routes 而不是 JSX:

      const routes = [];
      
      routes.push({
        path: 'path1',
        component: Component1
      });
      
      routes.push({
        path: 'path2',
        component: Component2
      });
      
      <Router routes={routes} history={browserHistory}/>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-28
        • 2016-10-21
        • 1970-01-01
        • 2019-09-09
        相关资源
        最近更新 更多