1. 为什么要用useState?
- 它是React 16.8 的新特性,我们在React里面一般都是用Class去写组件,但是有时候会发现不用它更方便,但是问题来了:不用Class的时候,数据的状态改变如何存储呢?
- 如果你用 var,let,const 等等,你会发现:值虽然改变了,但是页面并没有重新渲染,也就是说,这些关键字定义的值并不是响应式的。
- 这个时候,就轮到 useState 上场了,它允许我们定义状态变量,并且能保证在页面上能重新渲染,数据是响应式的。
2. 基本语法
const [state, setState] = useState(initialState);
- state => 存储的状态值
- setState => 用来修改状态的函数
- initialState => 首次渲染的初始值
- 比如 useState 返回一个数组,长度为 2
// 通常使用的定义方法
const [key, setKey] = useState(0);
// 但是怕大家不好理解,所以也可以拆开,如下:
const keyArr = useState(0);
const key = keyArr[0];
const setKey = keyArr[1];
3. 实践案例
const initData = [{imgSrc: '',contentStr: '第一条评论',},{imgSrc: '',contentStr: '第二条评论',},{imgSrc: '',contentStr: '第三条评论',},
];
import { useState, useEffect } from "react";
// useEffect 用于监听数据变化,不要也可以的
const BuyComment = () => {// 带入初始值const [dataList, setDataList] = useState(initData);// 重点在这里// 往数组里添加数据const addRule = () => {let obj = {imgSrc: [],contentStr: '新的评论',};// 有深拷贝的必要,防止数据出问题const addItems = JSON.parse(JSON.stringify(dataList));addItems.push(obj);// 在这里完成值的修改setDataList(addItems);};return (<div>{dataList.map((item, i) => {return (<div className={styles.mianBorder} key={i}>{item.contentStr}</div>);})}<div className={styles.addDiv}><span className={styles.addCom} onClick={addRule}>+ 添加评论</span></div></div>)
};
// 用于监听数据变化的
useEffect(() => {console.log(dataList);
}, [dataList]);
export default BuyComment;
- 做完以上的步骤,点击 添加评论 就会发现数据同步更改了。
4. useState 的惰性初始化
- useState 初始值是支持惰性初始化的,所以我们可以传递一个函数给它。
- 这个函数会在组件第一次渲染的时候执行,当然,后续的渲染就不会执行了。
- 之所以有这个特性,是为了优化性能。因为有时候我们会遇到非常庞大的数据处理,可能还要进行深拷贝,这些操作还是很耗性能的,如果每次组件渲染的时候都会执行,那代价是很大的,但又不是必须的,所以 useState 的优点就体现出来了:只执行一次,大大的减少了操作的性能和代价。
// 假设这里数据量非常大:jsonObj,我们需要对它进行解析,计算等等操作
const jsonObj = "{...}"; // 可能是一个很大的js 对象 或者json字符串function DemoComponent() {const [data, setData] = useState(() => {console.log("执行了")// 这种深拷贝是很耗性能的,所以我们在这里先把数据处理好,并且只处理一次return JSON.parse(JSON.stringify(jsonObj ));});
}
- 上面的代码中,打印只会执行一次。
- 避免重复的操作,提高代码性能。
1. 希望本文能对大家有所帮助,如有错误,敬请指出
2. 原创不易,还请各位客官动动发财的小手支持一波(关注、评论、点赞、收藏)
3. 拜谢各位!后续将继续奉献优质好文
4. 如果存在疑问,可以私信我(主页有Q)