ReactJs:不带索引的子键道具
您好,我试图在我的组件中使用索引作为键,但最终从eslint和reactjs自己的文档中得到错误,他们建议在最后一个选项中使用索引 通过研究,我发现了为每个组件生成uuid的方法,但这似乎成本很高 这是我的数组,我要用它:ReactJs:不带索引的子键道具,reactjs,Reactjs,您好,我试图在我的组件中使用索引作为键,但最终从eslint和reactjs自己的文档中得到错误,他们建议在最后一个选项中使用索引 通过研究,我发现了为每个组件生成uuid的方法,但这似乎成本很高 这是我的数组,我要用它: export const Tags: ITag[] = [ { Title: 'DashBoard', Name: 'Default', Link: '../dashboards', Icon: AiOutlineDashboard,
export const Tags: ITag[] = [
{
Title: 'DashBoard',
Name: 'Default',
Link: '../dashboards',
Icon: AiOutlineDashboard,
DropdownItems: null,
},
{
Name: 'Analytic',
Link: '../dashboards',
Icon: AiOutlineLineChart,
DropdownItems: null,
},
{
Name: 'Inventory',
Link: '../dashboards',
Icon: BiStoreAlt,
DropdownItems: null,
},
{
Title: 'Pages',
Name: 'Employees',
Link: '../dashboards',
Icon: TiGroupOutline,
DropdownItems: [
{Name: 'Employee List', Link: '/eloBost'},
{Name: 'View Employee', Link: '/duoBoost'},
{Name: 'New Employee', Link: '/eloBost'},
{Name: 'Any', Link: '/duoBoost'},
],
},
{
Name: 'Departaments',
Link: '../dashboards',
Icon: FaRegBuilding,
DropdownItems: [
{Name: 'Elo Boost', Link: '/eloBost'},
{Name: 'Duo Boost', Link: '/duoBoost'},
{Name: 'MD10', Link: '/eloBost'},
{Name: 'Coaching', Link: '/duoBoost'},
{Name: 'Vitóriais', Link: '/duoBoost'},
],
},
{
Name: 'Products',
Link: '../dashboards',
Icon: BsLightning,
DropdownItems: [
{Name: 'Elo Boost', Link: '/eloBost'},
{Name: 'Duo Boost', Link: '/duoBoost'},
{Name: 'MD10', Link: '/eloBost'},
{Name: 'Coaching', Link: '/duoBoost'},
{Name: 'Vitóriais', Link: '/duoBoost'},
],
},
{
Name: 'Suppliers',
Link: '../dashboards',
Icon: BsBookmarkPlus,
DropdownItems: [
{Name: 'Elo Boost', Link: '/eloBost'},
{Name: 'Duo Boost', Link: '/duoBoost'},
{Name: 'MD10', Link: '/eloBost'},
{Name: 'Coaching', Link: '/duoBoost'},
{Name: 'Vitóriais', Link: '/duoBoost'},
],
},
{
Name: 'Contracts',
Link: '../dashboards',
Icon: BsFileEarmarkText,
DropdownItems: [
{Name: 'Elo Boost', Link: '/eloBost'},
{Name: 'Duo Boost', Link: '/duoBoost'},
{Name: 'MD10', Link: '/eloBost'},
{Name: 'Coaching', Link: '/duoBoost'},
{Name: 'Vitóriais', Link: '/duoBoost'},
],
},
{
Name: 'User List',
Link: '../dashboards',
Icon: RiGroupLine,
DropdownItems: [
{Name: 'Elo Boost', Link: '/eloBost'},
{Name: 'Duo Boost', Link: '/duoBoost'},
{Name: 'MD10', Link: '/eloBost'},
{Name: 'Coaching', Link: '/duoBoost'},
{Name: 'Vitóriais', Link: '/duoBoost'},
],
},
];
在我的jsx上,我滚动列表并执行以下操作:
{tags.map((item) => (
<>
{item.Title ? (
<TitleItem key={generateKey(item.Title.toString())} open={open}>
{item.Title}
</TitleItem>
) : (
""
)}
<TagList
open={open}
key={generateKey(item.Name.toString())}
sideBarStatus={open}
tag={item}
clickHandler={clickHandler}
/>
</>
))}
ss:
带有控制台警告的codesandbox:
生成
uuid
可能比使用索引更糟糕。在大多数情况下,使用索引
值就可以了。有一个固定的id
用作键
值是理想的,因为它消除了在移动、重新排列项目和从列表中添加/删除时重新渲染的需要,但它实际上只是一种大多数程序都不需要的优化
也就是说,如果您有一个
id
,特别是对于来自外部服务器源的数据,请使用该id。如果这是一个静态列表,只需向对象添加id
属性。生成uuid
可能比使用索引更糟糕。在大多数情况下,使用索引
值就可以了。有一个固定的id
用作键
值是理想的,因为它消除了在移动、重新排列项目和从列表中添加/删除时重新渲染的需要,但它实际上只是一种大多数程序都不需要的优化
也就是说,如果您有一个
id
,特别是对于来自外部服务器源的数据,请使用该id。如果这是一个静态列表,只需向对象添加一个id
属性。问题在于包装器片段的使用。这就是它抱怨没有钥匙的原因。您将看到,如果将包装片段替换为具有键的DIV,则警告将消失。下面是您的更改示例:问题在于您对包装器片段的使用。这就是它抱怨没有钥匙的原因。您将看到,如果将包装片段替换为具有键的DIV,则警告将消失。下面是您的更改示例:在React
中,您应该使用key
来渲染列表,以便React
可以在渲染之间映射状态并进行最少数量的渲染。
如果未指定键
,则将使用元素的索引
。但你可能会面临警告
要解决此问题,您需要使用id
,但在渲染之间不会更改。
您的generateKeys
方法添加了当前日期,但这不是真的。因此,相反,会降低React
的性能
在您的情况下,可以使用名称
字段作为唯一键。
但请记住,最好使用id
,因为如果有两个元素具有相同的名称
字段,则会出现错误
而且您不需要在映射中提供多个键
。
键
仅由根元素所需。因此,在贴图中进行渲染的代码应如下所示:
<MenuList open={open}>
{tags.map((item) => (
<div key={item.Name}>
{item.Title ? <TitleItem open={open}>{item.Title}</TitleItem> : ""}
<TagList
open={open}
sideBarStatus={open}
tag={item}
clickHandler={clickHandler}
/>
</div>
))}
</MenuList>
{tags.map((项)=>(
{item.Title?{item.Title}:“}”
))}
我对Drop
组件做了一些修复,该组件也误用了键
可以看到更正后的代码
另外,我建议您阅读有关如何使用React
中中的键的更多详细信息。您应该使用key
来渲染列表,以便React
可以在渲染之间映射状态并进行最少数量的渲染。
如果未指定键
,则将使用元素的索引
。但你可能会面临警告
要解决此问题,您需要使用id
,但在渲染之间不会更改。
您的generateKeys
方法添加了当前日期,但这不是真的。因此,相反,会降低React
的性能
在您的情况下,可以使用名称
字段作为唯一键。
但请记住,最好使用id
,因为如果有两个元素具有相同的名称
字段,则会出现错误
而且您不需要在映射中提供多个键
。
键
仅由根元素所需。因此,在贴图中进行渲染的代码应如下所示:
<MenuList open={open}>
{tags.map((item) => (
<div key={item.Name}>
{item.Title ? <TitleItem open={open}>{item.Title}</TitleItem> : ""}
<TagList
open={open}
sideBarStatus={open}
tag={item}
clickHandler={clickHandler}
/>
</div>
))}
</MenuList>
{tags.map((项)=>(
{item.Title?{item.Title}:“}”
))}
我对Drop
组件做了一些修复,该组件也误用了键
可以看到更正后的代码
另外,我建议您阅读更多关于如何使用标记列表中的键的详细信息,您可以使用item.toString()-该项指示灯指向[object]字符串。例如,您应该执行item.Name.toString(),如果此警告中仍有帮助,您可以帮助我完成此操作吗?检查MenuTags
的渲染方法。有关详细信息,请参阅。您不应该在密钥中使用时间戳。这将导致不必要的重新渲染。如果您真的希望它脱离对象的字符串化版本,您可以将其字符串化JSON.stringify(item)
。为将要更改的密钥(如时间戳或uuid)生成的任何值都将是低效的,通常不被认为是一种好的做法。键应与其呈现的数据/内容相关。这有助于重新渲染与实际渲染紧密结合data@JohnRuddell你可以看看这里:我尝试使用json stringify,但我已经有了这个错误:检查菜单项的render方法。请参阅reactjs.org/link/warning-keys以了解标记列表中的更多信息
<MenuList open={open}>
{tags.map((item) => (
<div key={item.Name}>
{item.Title ? <TitleItem open={open}>{item.Title}</TitleItem> : ""}
<TagList
open={open}
sideBarStatus={open}
tag={item}
clickHandler={clickHandler}
/>
</div>
))}
</MenuList>