20 使用 Hooks之useState与useEffect

在Previous章节中,我们讨论了React Hooks的基本概念以及它们如何改变函数组件的状态管理和副作用处理。本节将深入探讨两个最常用的Hooks:useStateuseEffect。这两个Hooks不仅是React函数组件的核心组件,还能帮助我们轻松管理状态和处理副作用。

1. useState

useState是一个允许你在函数组件中添加状态的接口。其基本用法非常简单:你调用useState时,会得到一个包含当前状态值和更新该状态的函数的数组。

基本用法示例

以下是一个简单的计数器示例,展示如何使用useState来管理计数器的状态:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import React, { useState } from 'react';

const Counter: React.FC = () => {
// 定义一个状态变量count,并提供更新它的函数setCount
const [count, setCount] = useState(0);

return (
<div>
<p>当前计数: {count}</p>
<button onClick={() => setCount(count + 1)}>增加</button>
<button onClick={() => setCount(count - 1)}>减少</button>
</div>
);
};

在上述示例中,useState(0)创建了一个初始值为0的状态countsetCount函数用于更新该状态。

状态可以是任意类型

你可以将状态变量的类型设置为任意类型,这在管理复杂的状态时非常有用。例如,如果需要管理一个包含多个字段的对象状态,可以这样做:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
interface User {
name: string;
age: number;
}

const UserProfile: React.FC = () => {
const [user, setUser] = useState<User>({ name: '', age: 0 });

const updateName = (name: string) => {
setUser(prevUser => ({
...prevUser,
name
}));
};

return (
<div>
<input
type="text"
placeholder="输入名字"
onChange={(e) => updateName(e.target.value)}
/>
<p>用户: {user.name}, 年龄: {user.age}</p>
</div>
);
};

2. useEffect

useEffect是用于处理副作用的Hook,它可以在函数组件的每次渲染后运行某些代码,比如数据获取、订阅或手动操作DOM。

基本用法示例

下面的示例展示了如何使用useEffect来进行数据获取:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import React, { useEffect, useState } from 'react';

const DataFetching: React.FC = () => {
const [data, setData] = useState<any>(null);
const [loading, setLoading] = useState(true);

useEffect(() => {
const fetchData = async () => {
const response = await fetch('https://api.example.com/data');
const json = await response.json();
setData(json);
setLoading(false);
};

fetchData();
}, []); // 依赖数组为空,表示只在组件挂载时调用

if (loading) {
return <p>加载中...</p>;
}

return (
<div>
<h1>获取到的数据:</h1>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
);
};

在以上示例中,我们使用了useEffect来在组件首次渲染后执行fetchData函数,从而获取数据。依赖数组中的空数组意味着这个副作用只会在组件挂载时运行一次。

清理副作用

有时副作用需要清理,比如订阅或者定时器。useEffect可以返回一个函数,用于清理这些副作用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import React, { useEffect, useState } from 'react';

const Timer: React.FC = () => {
const [count, setCount] = useState(0);

useEffect(() => {
const interval = setInterval(() => {
setCount(prevCount => prevCount + 1);
}, 1000);

// 清理函数在组件卸载时调用
return () => clearInterval(interval);
}, []);

return <h1>秒数: {count}</h1>;
};

3. 结合使用useState和useEffect

结合使用useStateuseEffect可以实现更复杂的功能。我们可以创建一个简单的搜索框,在输入时进行API调用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import React, { useState, useEffect } from 'react';

const SearchComponent: React.FC = () => {
const [query, setQuery] = useState<string>('');
const [results, setResults] = useState<any[]>([]);
const [loading, setLoading] = useState(false);

useEffect(() => {
if (query) {
setLoading(true);
const fetchResults = async () => {
const response = await fetch(`https://api.example.com/search?q=${query}`);
const json = await response.json();
setResults(json.results);
setLoading(false);
};

fetchResults();
} else {
setResults([]);
}
}, [query]); // 依赖于query,当query变化时调用

return (
<div>
<input
type="text"
placeholder="输入搜索内容"
onChange={(e) => setQuery(e.target.value)}
/>
{loading ? <p>加载中...</p> : <ul>{results.map((item, index) => <li key={index}>{item}</li>)}</ul>}
</div>
);
};

在这个示例中,useEffect会在query变化时执行,进行数据获取。使用useState管理搜索的查询字符串和结果列表。

结论

useStateuseEffect是React中强大的Hooks,能够帮助我们灵活地管理组件状态和副作用。在构建复杂的应用时,合理运用这两个Hooks能够极大地简化逻辑和提高可读性。在接下来的章节中,我们将继续讨论如何创建自定义Hooks,以便复用逻辑并增强代码的灵活性。希望你在使用这些Hooks时能够得心应手!

20 使用 Hooks之useState与useEffect

https://zglg.work/react-tsx-zero/20/

作者

IT教程网(郭震)

发布于

2024-09-15

更新于

2024-09-16

许可协议

分享转发

交流

更多教程加公众号

更多教程加公众号

加入星球获取PDF

加入星球获取PDF

打卡评论