hooks是为了给函数式组件添加属性及声明周期等操作的添加,像类组件一样,实现动态化管理。
在函数组件中使用状态,修改状态值可让函数组件更新,类似于类组件中的setState
引入:
import React, { useState } from 'react'
let [num,setNum] = useState(initialValue);
- 执行useState,传递的initialValue是初始的状态值
- 执行这个方法,返回结果是一个数组:[状态值,修改状态的方法]
- num变量存储的是:获取的状态值
- setNum变量存储的是:修改状态的方法
- 执行 setNum(value)
- 修改状态值为value
- 通知视图更新
setState【修改状态的方法】 操作是异步的
列举:
const [current, setcurrent] = useState(0)
const [categoryList, setcategoryList] = useState([])
const [formInfo, setformInfo] = useState({})
const [content, setcontent] = useState("")
例子:
import React, { useState } from "react";
export default function Demo(props) {
let [num, setNum] = useState(10);
const handler = () => {
setNum(num + 1);
};
return <div>
<span>{num}</span>
<button onClick={handler}>新增</button>
</div>;
};
执行setNum,修改状态值为value,通知视图更新「组件重新渲染,同步生成一个新的作用域」 函数组件「或者Hooks组件」不是类组件,所以没有实例的概念「调用组件不再是创建类的实例,而是把函数执行,产生一个私有上下文而已」,再所以,在函数组件中不涉及this的处理!!
运行理解
函数组件的每一次渲染(或者是更新),都是把函数(重新)执行,产生一个全新的“私有上下文”!(闭包) 内部的代码也需要重新执行
内部的变量值操作都是按照作用域和作用域链进行操作的
- 涉及的函数需要重新的构建{这些函数的作用域(函数执行的上级上下文),是每一次执行DEMO产生的闭包}
- 每一次执行DEMO函数,也会把useState重新执行,但是:执行useState,只有第一次,设置的初始值会生效,其余以后再执行,获取的状态都是最新的状态值「而不是初始值」
- 返回的修改状态的方法,每一次都是返回一个新的
实现useState
var _state;
function useState(initialValue) {
if (typeof _state === "undefined") {
if(typeof initialValue==="function"){
_state = initialValue();
}else{
_state = initialValue
}
};
var setState = function setState(value) {
if(Object.is(_state,value)) return;
if(typeof value==="function"){
_state = value(_state);
}else{
_state = value;
}
// 通知视图更新
};
return [_state, setState];
}
let [num1, setNum] = useState(0); //num1=0 setNum=setState 0x001
setNum(100); //=>_state=100 通知视图更新
// ---
let [num2, setNum] = useState(0); //num2=100 setNum=setState 0x002