State Hook

State Hook 解决什么问题

state hook 可以用来给 函数组件 添加 state

没有 state hook 之前, 函数组件 属于 无状态组件,想给 函数组件 添加 state 时,只能将其转换为 class 组件。

State Hook 的使用方法

定义

1
2
import React, { useState } from 'react';
[stateName, setStateFun] = useState(initValue);

在函数组件中,通过调用 useState() 函数来定义 state 变量,它与 class 里面的 this.state 提供的功能相同。

useState 的返回值:返回一个有两个值的数组。第一个值是 state 变量,第二个值是更新 state 变量的函数。上面示例中,count 就是刚刚定义的 state 变量,setCount 就是用来更新 count 的函数。

useState 的参数:用来初始化 state 变量。下面示例中的参数 0,即表示 count 的初始值。

1
2
3
4
5
6
7
8
9
10
11
/*
定义:
1、引入useState函数
2、调用useState函数
*/
import React, { useState } from 'react';

function Example() {
// 声明一个叫 “count” 的 state 变量,和用来更新 count 的函数 setCount
const [count, setCount] = useState(0);
}

读取State

在 class 组件中,读取 state 变量时,通过 this.state,如 this.state.count。

1
<p>You clicked {this.state.count} times</p>

在函数组件中,读取 state 变量时,直接使用即可,如 count。

1
<p>You clicked {count} times</p>

更新State

在 class 组件中,需要调用 this.setState() 来更新 state 变量:

1
2
3
4
//setState 更新 State 时,会使用新值和旧值进行合并  
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click me
</button>

在函数组件中,使用 useState() 函数返回的 更新函数(如 setCount 函数)来更新对应的 state 变量:

1
2
3
4
//useState 更新 State 时,会直接用新值替换旧值
<button onClick={() => setCount(count + 1)}>
Click me
</button>

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 1:  import React, { useState } from 'react';
2:
3: function Example() {
//使用useState函数定义state变量
4: const [count, setCount] = useState(0);
5:
6: return (
7: <div>
{/*使用state变量*/}
8: <p>You clicked {count} times</p>

{//修改state变量}
9: <button onClick={() => setCount(count + 1)}>
10: Click me
11: </button>
12: </div>
13: );
14: }

定义多个 state 变量方法

  • 多次调用 useState

    1
    2
    3
    4
    5
    function ExampleWithManyStates() {
    // 声明多个 state 变量
    const [age, setAge] = useState(42);
    const [fruit, setFruit] = useState('banana');
    const [todos, setTodos] = useState([{ text: '学习 Hook' }]);
  • 将多个变量通过对象或数组的方式存入同一个 state 变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function Box() {
const [state, setState] = useState({ left: 0, top: 0, width: 100, height: 100 });

useEffect(() => {
function handleWindowMouseMove(e) {
// 展开 「...state」 以确保我们没有 「丢失」 width 和 height
// useState 更新 State 时,会用新值替换旧值,而不是新旧值合并
setState(state => ({ ...state, left: e.pageX, top: e.pageY }));
}
// 注意:这是个简化版的实现
window.addEventListener('mousemove', handleWindowMouseMove);
return () => window.removeEventListener('mousemove', handleWindowMouseMove);
}, []);
}