一、State Hook是啥?
State Hook 就是指 useState
这个特殊函数,让你不用编写class,就可以使用state特性,换言之就是让 函数组件 拥有 state 特性,对数据进行动态更新。
二、class中的state
动态改变数据,譬如一个计数器组件,class组件中实现方式如下:
class Example extends React.Component {
constructor(props) {
super(props);
// 只能在构造函数中初始化state
this.state = {
count: 0
};
}
// 只能调用 this.setState 方法来更新 count 值
render() {
return (
<div>
<p>You clicked {this.state.count} times</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click me
</button>
</div>
);
}
}
三、useState怎么用?
1、简单实例
在函数组件中,用 useState
实现计数器功能,跟上面class实现一样的功能。
import React, { useState } from 'react';
function Example() {
// 声明 `count` 的 state 变量 和 用于改变 `count` 的setCount方法;
const [count, setCount] = useState(0);
// 上面这一句是js中数组解构语法,其实它等同于下面这几句:
// var countStateVariable = useState(0); // 返回一个有两个元素的数组
// var count = countStateVariable[0]; // 数组里的第一个值
// var setCount = countStateVariable[1]; // 数组里的第二个值
// count 和 setCount 是函数内部的变量和方法,可直接访问
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
2、可使用多个state
function ExampleWithManyStates() {
// 声明多个 state 变量,且他们都是相互独立的
const [age, setAge] = useState(42);
const [fruit, setFruit] = useState('banana');
const [todos, setTodos] = useState([{ text: '学习 Hook' }]);
3、函数式更新
setCount( c => c +1 )
这种方式就是函数式更新,确保了 count 更新总是建立在最新的数据上,让你从 count 的管理中解脱出来。如下实例,一个计数器,count 数值的变化,永远基于最新数值,让你不用去管理count。
function Counter({ initialCount }) {
const [count, setCount] = useState(initialCount);
return (
<>
Count: {count}
<button onClick={() => setCount(initialCount)}>Reset</button>
<button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
<button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
</>
);
}
备注:此功能用在 useEffect
中,会非常方便。
4、惰性初始化
useState 的初始化,可以通过传入函数的方式进行,适用于复杂计算后的结果。
const [state, setState] = useState(() => {
const initialState = someExpensiveComputation(props);
return initialState;
});
5、跳过 state 更新
调用 useState 的更新方法来更新state,如果新 state 数值跟之前是一样的,那么组件会跳过子组件的渲染和 useEffect 的调用。
四、合并更新
class组件中的 setState 会自动合并更新 state 对象。useState 可通过 展开运算符
、 Object.assign
、 useReducer
来合并更新对象。
1、展开运算符
const [state, setState] = useState({});
setState(prevState => {
return { ...prevState, ...updatedValues };
});
2、Object.assign
const [state, setState] = useState({});
setState(prevState => {
return Object.assign(prevState, updatedValues);
});
3、useReducer
更适合用于管理包含多个子值的 state 对象。