Warning: Each Child in a list should have a unique "Key" prop.
我相信我不是唯一一个对React的钥匙系统感到困惑的人。此问题主要关注添加键
道具的包容性情况。
我所做的相关阅读包括:
>
肯特·多德理解反应的关键支柱
了解React.js数组子元素的唯一键
根据Adhiti Ravichandran的说法,迭代中的键有助于识别哪些项已更改(添加/删除/重新排序)
考虑以下电影组件:
class Movie extends React.Component<any, any> {
render():JSX.Element{
let styles:React.CSSProperties = {
width: "300px",
height: "120px",
display: "flex",
justifyContent: "space-around",
alignItems: "center",
borderRadius: "20px",
filter: "drop-shadow(0px 1px 3px #6d6d6d)",
WebkitFilter: "drop-shadow(3px 3px 3px #6d6d6d)",
backgroundColor: '#'+Math.floor(Math.random()*16777215).toString(16),
fontSize: '2.5rem',
margin: '20px',
color: '#fff',
}
return (
<>
{/* add key to this div tag? */}
<div style={styles}>
{this.props.title}
</div>
</>
)
}
}
function test():JSX.Element{
return (
<>
{
['The Avengers', 'Ip Man', 'Now You See Me'].map(
// or add key to this Movie tag?
title=>(<Movie title={title} />)
)
}
</>
);
}
class Singleton {
private static _instance:Singleton = new Singleton();
public _ind:number = 0;
public _ids:Array<string> = ['r0'];
public _memory:boolean = false;
public _remember:Array<string|boolean|number> = [];
constructor(){
if(Singleton._instance){
return Singleton._instance;
}
Singleton._instance = this;
}
public new():string{
this._ind += 1;
this._ids.push(`r${this._ind}`);
let tar = this._ids[this._ids.length-2];
if(this._memory){this._remember.push(tar)}
return tar;
}
public placeholder(cos:string|boolean|number):void{
if(this._memory){this._remember.push(cos)}
}
public last():string{
return this._ids[this._ids.length-2];
}
public start_memorize():void{
this._memory = true;
}
public end_memorize():void{
this._memory = false;
}
public dump_memory():Array<string|boolean|number>{
let tar = this._remember.concat();
this._remember = [];
return tar;
}
public redeem(num:number){
for(let i=0; i<num; i++){
this._ids.pop();
this._ind -= 1;
}
}
}
export default Singleton;
而Singleton.new()
被调用来解析一个新的键,以下面为例:
class Card extends React.Component<any, any>{
props:React.ComponentProps<any>;
singleton:Singleton;
constructor(props:any) {
super(props);
this.singleton = new Singleton();
}
render(){
return (
<>
<div key={this.singleton.new()}>
</div>
</>
)
}
}
从概念上讲,React分两个阶段工作:
在渲染阶段,为了将当前结果(React组件/元素树)与上一个渲染结果(React组件/元素树)进行比较,React使用协调算法。
在此比较过程中,React使用键
将当前结果中的组件/元素与上一个渲染结果中的组件/元素相匹配。
如果键
相同,只需更新组件/元件即可。
>
组件
组件实例保持不变,以便在渲染过程中保持状态。组件实例调用componentWillReceiveProps()、componentWillUpdate()和componentDidUpdate()。
对于元素
React保留相同的基础DOM节点,只更新更改的属性。
如果键不相同,React将创建新的组件/元素
>
组件
组件实例被初始化。组件实例先调用组件WillMount(),然后调用组件DDMount()。
对于元素,新的DOM节点被插入到DOM中。
如果带有
键
的组件/元素出现在先前的结果中,但不在当前结果中,那么React将删除它们。
>
组件
组件实例调用componentWillUnmount()。与旧实例关联的任何状态都将丢失。组件实例被销毁。
对于元素,旧的DOM节点被销毁。
回答你的问题
对于组件生产,是否应该在迭代或组件渲染方法中添加关键点?
应该在迭代中添加键,以唯一地标识列表中呈现的子组件/元素。
<Movie title={title} key={title} />
如果将键添加到div,则警告不会消失。但上述对账规则将适用于div元素。
使用单例id解析器生成密钥是否合适?
如果单例id解析器生成不稳定的键,比如
Math。随机的
就没有用了。密钥应该是稳定的、可预测的和唯一的。
这种说法正确吗?"键道具仅对超文本标记语言原始标记有用,如div、span、按钮,但对React无效。组件如果this.props.key未使用。
在您和文档中,键有助于识别哪些项目已更改、已添加或已删除。因此,在我的透视图中,项目同时指组件和元素。因此,键适用于组件和元素。我在两者中都使用它。
本节要介绍的 infer 关键字有些难理解,我们来通过一个类比来帮助理解。 语句 let num 中,通过 let 来声明了一个变量,那怎样声明一个不确定的类型变量呢? 答案是使用 infer 关键字,infer R 就是声明了一个类型变量 R。 1. 慕课解释 在条件类型表达式中,可以在 extends 条件语句中使用 infer 关键字来声明一个待推断的类型变量。 2. 通过 ReturnTy
本节介绍 TypeScript 中的 is 关键字,它被称为类型谓词,用来判断一个变量属于某个接口或类型。如果需要封装一个类型判断函数,你应该第一时间想到它,本节列出了一些常用的类型判断函数以供参考。 1. 慕课解释 is 关键字一般用于函数返回值类型中,判断参数是否属于某一类型,并根据结果返回对应的布尔类型。 语法:prop is type 2. 举例说明 在一些兑换码场景,经常会需要将兑换码全
乍一看,这似乎并不是非常有用(即使是错误提及原始类型),但随着类型注释变得更加复杂, 关键字的好处变得明显。 联合类型允许类型注释指定属性应该是一组类型之一(两者任一)。 function admitAge (age: number|string): string { return `I am ${age}, alright?!`; } admitAge('Forty'); // 'I am
React/Typescript中对象的类型是什么,例如: 如果我需要将它定义为一个对象,我应该输入什么类型,而不是
react-typescript 项目概况 使用Ant-Design开发的一套后台管理系统,主要用到了React、Typescript、Mobx、PWA等技术,使用webpack5打包构建,包含React16的一些新特性。 项目主要技术结构 react typescript antd mobx webpack4 react-router4 pwa 安装 在终端下操作 项目地址: (git clon
问题内容: 我有一个简单的以React- Redux为动力的表格。我希望有一个form.container.tsx和form.component.tsx,其中form.container.tsx保留了到redux状态减去Field的所有连接。我试图将我的容器包装在react- redux的connect中,然后将reduxForm包装在其中,使其看起来像TypeScript,redux- form