02 useState基础用法
useState概念解释
我们第一个要学习的Hook(钩子函数)是useState,他的作用是“勾住”函数组件中自定义的变量。
“勾住”?
回顾一下 “React Hook 简介” 文中那句话:Hook本身单词意思是“钩子”,作用就是“勾住某些生命周期函数或某些数据状态,并进行某些关联触发调用”。
“如何勾住”? 在React底层代码中,是通过自定义dispatcher,采用“发布订阅模式”实现的。
关于“钩子”、“勾住”、“如何勾住”的概念以后在学习其他Hook函数时不再做解释。
useState是来解决类组件什么问题的?
答:useState能够解决类组件 所有自定义变量只能存储在this.state 的问题。
举例:若某组件需要有2个自定义变量name和age,那么在类组件中只能如下定义
constructor(props) {
super(props);
this.state = {
name:'puxiao',
age:34
}
}
name和age只能作为this.state的一个属性。
没有对比就没有伤害,看一下使用useState后,函数组件是如何实现上述需求的
const [name,setName] = useState('puxiao');
const [age,setAge] = useState(34);
1、函数组件本身是一个函数,不是类,因此没有构造函数constructor(props);
2、任何你想定义的变量都可以单独拆分出去,独立定义,互不影响;
两段代码对比之下,你就会发现使用Hook的useState后,会让我们定义的变量相对独立,清晰简单,便于管理。
接下来开始学习useState。
useState函数源码:
首先看一下React源码中的ReactHooks.js。
//备注:源码采用TypeScript编写,如果不懂TS代码,阅读起来稍显困难
export function useState<S>(
initialState: (() => S) | S,
): [S, Dispatch<BasicStateAction<S>>] {
const dispatcher = resolveDispatcher();
return dispatcher.useState(initialState);
}
上述代码看不懂没关系,本系列教程只是讲述“如何使用Hook”,并不是“Hook源码分析”。之所以贴出源码只是为了显得本文比较有深度。^_^
更新于2020.11.10,这里强调一下:React 源码中使用的是 flow 语法,根本不是 TypeScript 语法,只不过 2 者实在是太像了,以至于让我之前一直误以为 React 源码中是 TS。不过你完全可以将 TS 的泛型知识去套用到 flow 中。在此特别说明一下,至于后续章节中就不再做提醒和修改了,你就当成 TS 语法去理解也行。
补充一些TypeScript常识:
1、react 本身采用TypeScript编写,还是补充点TS常识,方便对各个 hook 函数源码的理解。
2、对于useState以及以后要学习的其他hook函数源码,函数参数中会反复出现<S\>
、<T\>
、<P\>
、<I\>
、<I\>
,这些大写字母,react约定他们对应的单词如下:
state -> S ->
约定表示某种“数据”
type -> T ->
约定表示某种“类型”
props -> P ->
约定表示“属性传值对应的props”
initial -> I ->
约定表示某个“初始值”
1、这种用<X\>
包裹起来的类型声明,在TS中成为“泛型”。理论上是可以使用任意单词的,上面那些缩写只是react自己约定单词缩写。
2、对于一段TS代码,如果出现了<S\>
,那么后面所有的<S\>
都将表示“某种相同类型的数据”。对于TypeScript的泛型相关知识,请自己百度学习。
useState基本用法
useState(value)函数会返回一个数组,该数组包含2个元素:第1个元素为我们定义的变量,第2个元素为修改该变量对应的函数名称。