← 返回目录

第 14 卷

第 14 / 28 卷日期:

4import useRequest from './useRequest';

5 6// 定义请求函数(获取用户列表)

7const fetchUserList = async () => {

8const response = await fetch('https://api.example.com/users');
9return response.json();
10};

11 12function UserList() {

13// 调用自定义 Hook,传入请求函数和依赖数组 14const { data: userList, loading, error, refetch } =

useRequest(fetchUserList, []);

15 16if (loading) return <div>加载中...</div>;

17if (error) return <div>请求失败:{error}</div>;

18 19return (

20<div> 21<h3>用户列表</h3>

22<ul> 23{userList?.map(user => (

24<li key={user.id}>{user.name}</li> 25))}

26</ul>

27<button onClick={refetch}>刷新列表</button>
28</div>
29);
30 }

31 32export default UserList;

(3)示例 2:封装表单状态管理的自定义 Hook(useForm)

场景:多个表单组件需要处理“输入值绑定、表单重置、表单验证”逻辑,抽取为自定义 Hook。

Code block

1 2// 1. 定义自定义 Hook:useForm.js

3import { useState } from 'react';

11

12//处理输入变化(绑定到input的onChange)
13const handleChange = (e) => {
14const { name, value } = e.target;
15setValues(prev => ({ ...prev, [name]: value }));
16};

17 18// 表单验证逻辑

19const validate = () => { 20const newErrors = {};

21// 示例:验证用户名和密码不为空

22if (!values.username) newErrors.username = '用户名不能为空';
23if (!values.password) newErrors.password = '密码不能为空';
24setErrors(newErrors);
25//返回是否验证通过
26return Object.keys(newErrors).length === 0;
27};

28 29// 表单提交处理

30const handleSubmit = (onSubmit) => (e) => {
31e.preventDefault();
32const isValid = validate();
33if (isValid) {
34onSubmit(values);//执行组件传入的提交逻辑
35}
36};

37 38// 表单重置

39const resetForm = () => { 40setValues(initialValues);

41setErrors({});

42};

43 44// 返回表单相关的状态和方法

45return { values, errors, handleChange, handleSubmit, resetForm };

46} 47

48export default useForm;

使用自定义 Hook 的表单组件:

5 6function LoginForm() {

7// 调用自定义 Hook,传入初始表单值

8const { values, errors, handleChange, handleSubmit, resetForm } = useForm({
9username: '',
10password: ''
11});

12 13// 表单提交逻辑

14const onLogin = (formValues) => {

15console.log('提交登录信息:', formValues);
16//此处可添加发送登录请求的逻辑
17};

18 19return (

20<form onSubmit={handleSubmit(onLogin)}> 21<div>

22<label>用户名:</label> 23<input

24type="text"

25name="username"

26value={values.username} 27onChange={handleChange}

28/> 29{errors.username && <span style={{ color: 'red' }}>{errors.username}

</span>} 30</div>

31<div> 32<label>密码:</label>

33<input 34type="password"

35name="password"

36value={values.password} 37onChange={handleChange}

38/> 39{errors.password && <span style={{ color: 'red' }}>{errors.password}

</span>} 40</div>

41<button type="submit">登录</button> 42<button type="button" onClick={resetForm} style={{ marginLeft: '10px' }}>

重置</button> 43</form>

全站分卷索引 · 28 卷
  1. 1第 1 卷
  2. 2第 2 卷
  3. 3第 3 卷
  4. 4第 4 卷
  5. 5第 5 卷
  6. 6第 6 卷
  7. 7第 7 卷
  8. 8第 8 卷
  9. 9第 9 卷
  10. 10第 10 卷
  11. 11第 11 卷
  12. 12第 12 卷
  13. 13第 13 卷
  14. 14第 14 卷
  15. 15第 15 卷
  16. 16第 16 卷
  17. 17第 17 卷
  18. 18第 18 卷
  19. 19第 19 卷
  20. 20第 20 卷
  21. 21第 21 卷
  22. 22第 22 卷
  23. 23第 23 卷
  24. 24第 24 卷
  25. 25第 25 卷
  26. 26第 26 卷
  27. 27第 27 卷
  28. 28第 28 卷