一、useReducer 基本用法

  1. const [state, dispatch] = useReducer(reducer, initialArg, init)
  1. useReducer接收两个参数。第一个参数:reducer 函数。第二个参数:初始化的 state。返回值为最新的state和dispatch函数(用来触发reducer函数,计算对应的state)。
  2. 按照官方的说法:对于复杂的state操作逻辑,嵌套的state的对象,推荐使用useReducer,所以说useReducer是useState复杂情况下的替代方案。

    二、useState和useReducer复杂场景下的使用对比

  • 常规 useState 写法 ```javascript function LoginPage() {

    1. const [name, setName] = useState(''); // 用户名
    2. const [pwd, setPwd] = useState(''); // 密码
    3. const [isLoading, setIsLoading] = useState(false); // 是否展示loading,发送请求中
    4. const [error, setError] = useState(''); // 错误信息
    5. const [isLoggedIn, setIsLoggedIn] = useState(false); // 是否登录
    6. const login = (event) => {
    7. event.preventDefault();
    8. setError('');
    9. setIsLoading(true);
    10. login({ name, pwd })
    11. .then(() => {
    12. setIsLoggedIn(true);
    13. setIsLoading(false);
    14. })
    15. .catch((error) => {
    16. // 登录失败: 显示错误信息、清空输入框用户名、密码、清除loading标识
    17. setError(error.message);
    18. setName('');
    19. setPwd('');
    20. setIsLoading(false);
    21. });
    22. }
    23. return (
    24. // 返回页面JSX Element
    25. )

    }

  1. - useReducer写法
  2. ```javascript
  3. const initState = {
  4. name: '',
  5. pwd: '',
  6. isLoading: false,
  7. error: '',
  8. isLoggedIn: false,
  9. }
  10. function loginReducer(state, action) {
  11. switch(action.type) {
  12. case 'login':
  13. return {
  14. ...state,
  15. isLoading: true,
  16. error: '',
  17. }
  18. case 'success':
  19. return {
  20. ...state,
  21. isLoggedIn: true,
  22. isLoading: false,
  23. }
  24. case 'error':
  25. return {
  26. ...state,
  27. error: action.payload.error,
  28. name: '',
  29. pwd: '',
  30. isLoading: false,
  31. }
  32. default:
  33. return state;
  34. }
  35. }
  36. function LoginPage() {
  37. const [state, dispatch] = useReducer(loginReducer, initState);
  38. const { name, pwd, isLoading, error, isLoggedIn } = state;
  39. const login = (event) => {
  40. event.preventDefault();
  41. dispatch({ type: 'login' });
  42. login({ name, pwd })
  43. .then(() => {
  44. dispatch({ type: 'success' });
  45. })
  46. .catch((error) => {
  47. dispatch({
  48. type: 'error'
  49. payload: { error: error.message }
  50. });
  51. });
  52. }
  53. return (
  54. // 返回页面JSX Element
  55. )
  56. }