我想将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>
虽然这有效,但我得到的警告是迭代器的所有子节点,即路由,都应该有一个关键支柱:
Each child in an array or iterator should have a unique "key" prop.
但在这种情况下钥匙真的是必要的吗?根据我的理解,即使我使用数组,路线也只渲染一次并且不是动态的。
是否可以在React中执行此操作?
答案 0 :(得分:2)
因为你正在使用一个表达式(而不是硬编码/预配置的子节点),并且因为表达式被评估为一个数组,所以React认为这是一个带有动态子节点的组件,因此它开始用它来警告你信息。
考虑更多,这是有道理的。因为就React而言,没有什么能阻止您修改该数组并期望表达式解析为不同的数据集。因此它认为它是一个充满活力的孩子的组成部分。
答案 1 :(得分:1)
根据我的理解,即使我使用数组,路线也只渲染一次并且不是动态的。
即使<Router>
只渲染一次,它仍然是一个React组件,它不会意识到它只会渲染一次&#34;。该组件需要准备好重新呈现&#39;并且有效地做到了。
为了确保组件有效渲染,它会要求提供这些&#34;键&#34;。
你可以在这里停止阅读我的回复,但如果你想围绕它建立更多的直觉,继续阅读:)
想象一下,你目睹了一个小偷偷了一位老太太的钱包......
警察带你进入阵容中识别坏人。阵容室外有8名嫌犯。警官带来了房间里的前6名嫌犯。由于房间容量问题,其他2人正在外面等候。
他们每个人都持有一个ID标签(键)。你仔细看看每一个,然后在纸上写下他们的ID。你仍然需要看到其他2个嫌疑人,但根据法律规定,排队的房间必须总共有6个人。这意味着你刚刚看到的4个将保留在阵容室中。
因为你非常聪明并且记下了你已经看过的嫌疑人的身份证件(看看=渲染),你可以跳过查看嫌疑人的身份证已经在你的名单中。< / p>
我知道这是一个奇怪的例子,但我希望它有所帮助:)
如果您想了解更多详情,请参阅React文档:https://facebook.github.io/react/docs/reconciliation.html#list-wise-diff
答案 2 :(得分:0)
如果您向没有特定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是您将道具传递给的组件。
答案 3 :(得分:0)
一个简单的解决方案是使用Plain Routes而不是JSX:
const routes = [];
routes.push({
path: 'path1',
component: Component1
});
routes.push({
path: 'path2',
component: Component2
});
<Router routes={routes} history={browserHistory}/>