react中的key属性,它是一个特殊的属性,它是出现不是给开发者用的(例如你为一个组件设置key之后不能获取组件的这个key props),而是给react自己用的。
react利用key来识别组件,它是一种身份标识标识。每个key对应一个组件,相同的key react认为是同一个组件,这样后续相同的key对应组件都不会被创建。
key相同,若组件属性有所变化,则react只更新组件对应的属性;没有变化则不更新。key值不同,则react先销毁该组件(有状态组件的componentWillUnmount会执行),然后重新创建该组件(有状态组件的constructor和componentWillUnmount都会执行)
key不是用来提升react的性能的,不过用好key对性能是有帮组的。
为何由数组动态创建的组件必须要用到key属性呢?这跟数组元素的动态性有关。
拿上述用户列表的例子来说,看一下babel对上述代码的转换情况:
// 转换前
const element = (
<div>
<h3>用户列表</h3>
{[<div key={1}>1:张三</div>, <div key={2}>2:李四</div>]}
</div>
);
// 转换后
"use strict";
var element = React.createElement(
"div",
null,
React.createElement("h3",null,"用户列表"),
[
React.createElement("div",{ key: 1 },"1:张三"),
React.createElement("div",{ key: 2 },"2:李四")
]
);
有babel转换后React.createElement中的代码可以看出,其它元素之所以不是必须需要key是因为不管组件的state或者props如何变化,这些元素始终占据着React.createElement固定的位置,这个位置就是天然的key。
而由数组创建的组件可能由于动态的操作导致重新渲染时,子组件的位置发生了变化,例如上面用户列表子组件新增一个用户,上面两个用户的位置可能变化为下面这样:
var element = React.createElement(
"div",
null,
React.createElement("h3",null,"用户列表"),
[
React.createElement("div",{ key: 3 },"1:王五"),
React.createElement("div",{ key: 1 },"2:张三"),
React.createElement("div",{ key: 2 },"3:李四")
]
);
可以看出,数组创建子组件的位置并不固定,动态改变的;这样有了key属性后,react就可以根据key值来判断是否为同一组件。
另外,还有一种比较常见的场景:为一个有复杂繁琐逻辑的组件添加key后,后续操作可以改变该组件的key属性值,从而达到先销毁之前的组件,再重新创建该组件。
key的值要稳定唯一,不要使用index作为key。
{
this.state.type ?
<div><Son_1/><Son_2/></div>
: <div><Son_2/><Son_1/></div>
}
例如上面代码中,this.state.type的值改变时,原Son_1和Son2组件的实例都将会被销毁,并重新创建Son_1和Son_2组件新的实例,不能继承原来的状态,其实他们只是互换了位置。为了避免这种问题,我们可以给组件加上key。
{
this.state.type ?
<div><Son_1 key="1"/><Son_2 key="2"/></div>
: <div><Son_2 key="2" /><Son_1 key="1"/></div>
}
这样,this.state.type的值改变时,Son_1和Son2组件的实例没有重新创建,react只是将他们互换位置。
var F=function(){
//this指向谁,在定义时是不知道的
};
var p=new F;
用new调用一个函数发生了这些事:
(1)新建一个对象instance=new Object();
(2)设置原型链instance.__proto__=F.prototype;
(3)让F中的this指向instance,执行F的函数体。
(4)判断F的返回值类型:如果是值类型,就丢弃它,还是返回instance。如果是引用类型,就返回这个引用类型的对象,替换掉instance。
1.实例是子类的实例,也是父类的实例
2.创建子类实例时,可以向父类的构造函数传参
3.可以访问父类的属性和方法,也可以访问父类原型的属性和方法
4.可以实现多继承
水平居中元素:
通用方法,元素的宽高未知
方式一:CSS3 transform
.parent {
position: relative;
}
.child {
position: absolute;
left: 50%;
transform: translateX(-50%);
}
方式二:Flex 布局
.parent {
display: flex;
justify-content: center;
}
适用于子元素为浮动,绝对定位,内联元素,均可水平居中。
居中的元素为常规文档流中的内联元素(display: inline)
常见的内联元素有:span, a, img, input, label 等等
.parent {
text-align: center;
}
此方法同样适用于 display: inline-block 的元素。
居中的元素为常规文档流中的块元素(display: block)
常见的块元素:div, h1~h6, table, p, ul, li 等等
方式一:设置 margin
.parent {
width: 100%;
}
.child {
width: 600px;
height: 50px;
margin: 0 auto;
background: #999;
}
此方法只能进行水平的居中,且对浮动元素或绝对定位元素无效。
方式二:修改为 inline-block 属性
.parent {
text-align: center;
}
.child {
display: inline-block;
}
居中的元素为浮动元素
.child {
width: 100px;
float: left;
position: relative;
left: 50%;
margin-left: -50px;
}
居中的元素为绝对定位元素
方式一:
.parent {
position: relative;
}
.child {
position: absolute;
width: 100px;
left: 50%;
margin-left: -50px;
}
方式二:
.parent {
position: relative;
}
.child {
position: absolute;
width: 100px;
left: 0;
right: 0;
margin: 0 auto;
}
垂直居中元素:
通用方法,元素的宽高未知
方式一:CSS3 transform
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
方式二:Flex 布局
.parent {
display: flex;
align-items: center;
}
适用于子元素为浮动,绝对定位,内联元素,均可垂直居中。
居中元素为单行文本
.text {
line-height: 200px;
height: 200px;
}
把文字的 line-height 设为文字父容器的高度,适用于只有一行文字的情况。
已知元素宽高
方式一:
.parent {
position: relative;
}
.child{
position: absolute;
top: 50%;
height: 100px;
margin-top: -50px;
}
方式二:
.parent {
position: relative;
}
.child{
position: absolute;
top: 0;
bottom: 0;
height: 100px;
margin: auto 0;
}
垂直居中元素:
1. 绝对居中定位
div {
width: 100px;
height: 100px;
margin: auto;
position: fixed;
//absolute is ok
top: 0;
right: 0;
bottom: 0;
left: 0;
}
优点:
不仅可以实现在正中间,还可以在正左方,正右方
元素的宽高支持百分比 % 属性值和 min-/max- 属性
可以封装为一个公共类,可做弹出层
浏览器支持性好
2. 负边距居中
.child {
width: 100px;
height: 100px;
position: absolute;
top: 50%;
left: 50%;
margin-left: -50px;
margin-top: -50px;
}
特点:
良好的跨浏览器特性,兼容 IE6 - IE7
灵活性差,不能自适应,宽高不支持百分比尺寸和 min-/max- 属性
3. Transform 定位
.child {
width: 100px;
height: 100px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
特点:
内容可自适应,可以封装为一个公共类,可做弹出层
可能干扰其他 transform 效果
4. Flexbox 布局
.parent {
display: flex;
justify-content: center;
align-items: center;
}
这是 CSS 布局未来的趋势。Flexbox 是 CSS3 新增属性,设计初衷是为了解决像垂直居中这样的常见布局问题。
5. table-cell 居中
.parent {
display: table-cell;
vertical-align: middle;
text-align: center;
width: 200px;
height: 200px;
border: 1px solid red;
}
.child {
width: 100px;
height: 100px;
display: inline-block;
background-color: #03f;
}
适用于子元素 display 为 inline-block, inline 类型的元素,需要已知父元素的宽高,且父元素的宽高不能设为百分比数。
6. font-size 配合 vertical-align 实现垂直居中
.parent {
font-size: 175.4px;
height: 200px;
text-align: center;
}
.child {
vertical-align: middle;
display: inline-block;
font-size: 12px;
width: 50px;
height: 50px;
background-color: #00f;
}
该方法的要点是给父元素设一个合适的 font-size 的值,这个值的取值为该父元素的高度除以 1.14 得到的值,并且子元素必须 是一个 inline 或 inline-block 元素,需要加上 vertical-align: middle 属性。使用这种方法,子元素的宽度或高度都不必知道。
具体原理可以上网搜 vertical-align 垂直居中。
7. 文本内容居中
text {
height: 100px;
line-height: 100px;
text-align: center;
}