道阻且长,行而不辍,未来可期
Hook是React 16.8.0版本增加的新特性
state hook让函数组件也有状态,也可以进行状态的读写。
语法:const [xxx,setXxx] = React.useState(initValue);
useState()说明:
参数:第一次初始化指定的值在内部做缓存
返回值:包含2个元素的数组,
第1个为内部当前状态值(immutable类型的状态值)
第2个为更新该状态的函数
setXxx()有2中写法:
setXxx(newValue):参数为非函数值,直接指定新的状态值,内部用其覆盖原来的状态值
setXxx(value=>newValue):参数为函数,返回新的状态值,内部用其覆盖原来的状态值
好了,概念介绍完了,看起来没什么不容易理解的。
但是我发现我身边好些人会忽略?为什么要指定新的状态值
但是React中的state是不可变数据immutable
不可变数据就是不可以直接去修改它的值,而是要通过复制他的值,并且产生一个新的对象的方式来得到一个新的数据,这个新的数据包含了你要修改的部分。
简言之就是不可变数据,不可以直接修改,若要修改,必须对它进行一份复制,无论是浅复制,还是深复制
在JS中,如果往数组里追加一个数据,数组的引用是不会变的,它仍然指向原来的地址。
React无法感知到数组内容的变化,必须使用一个新数组替换旧数组(引用不一样就行,就比如{} {}两个对象虽然都是空的,但是引用不一样)
例如:
const [list,setList]=useState(["apple","orange"]);
list是immutable
若想往list中追加新的数据,
错误方法:
setList(preState=>preState.push("peach"))
因为Array.push()会直接更改原数组的值,违背了immutable
正确方法:
setList(preState=>preState.concat("peach"));
Array.concat(…items)用于连接两个或多个数组,它会返回一个新数组,不会修改原数组。
setList(preState=>[...preState,"peach"])
也可以使用扩展运算符,将数组转化为逗号分隔的参数序列,
创建一个新的数组
注意:…不适合多级数组或带有日期或函数的数组
数组中常用的不改变原数组的方法:
Array.concat(...items)用于连接两个或多个数组,它会返回一个新数组,不会修改原数组。
Array.filter(callback):返回满足条件的新数组,不改变原数组
Arrap.map(callback):返回新的数组,不改变原来的数组
Array.slice(start,end):返回指定部分的新数组,不会改变原数组
Array.reduce(callback):累加器
改变原数组的方法:
Array.push();向数组尾部添加元素
Array.unshift();向数组开头添加元素
Array.pop();删除数组末尾的元素
Array.shift();删除数组的第一个元素
Array.splice();插入/删除数组的元素
数组解构:
const [a,b,c]=[1,2,3]
这里数组通过解构给变量a,b,c 分别赋值,这里的变量也可以是d,e,f
对象解构:
const obj = {
name:'锦城',
age:100
}
const {name,age} = obj;
name 和 age 经过解构被赋值,它们的次序是可以被改变的,写成 const {age,name}=obj 完全没问题
可以发现,解构不仅可以用于数组,还可以用于对象,对象的解构和数组的解构有一个重要的不同。
数组的元素是按次序排列的,变量的取值由它的位置决定。比如上面的a对应的就是数组的第一项1;
而对象的属性是没有次序的;数组解构时的变量可以是任意名字,不会影响它的取值,
而对象的变量必须和属性同名,才能取到正确的值。