代码 CR(一)

194 阅读1分钟

状态合并

看一下如下代码,不知道大家会有什么感想?

const Demo = ()=> {
  const [state1, setState1] = React.useState('');
  const [state2, setState2] = React.useState('');
  const [state3, setState3] = React.useState('');
  // 4,5,6,7....
  
  return <div>xxx</div>
}

函数组件通过 useState 更新状态,这就会出现一个组件内出现大量 useState,看上去很不爽,但又没什么毛病。

是否可以像类组件一样,通过 setState 维护多个状态呢?

当然,我们改造一下。

const Demo = ()=> {
  const [state, produce] = React.useState({
    state1: '',
    state2: '',
    state3: ''
  });
  const setState = (newState) => {
    produce({
      ...state,
      ...newState
    })
  }

  return <div>xxx</div>
}

咋一看代码还多了呢?这是因为我们简写了代码,让你产生了误解,实际项目中可能会有 N 个 useState 。

是否需要封装 useState 取决于实际情况,如果组件内 useState 过多的话可以仔细考虑下组件拆分是否合理。

数据请求

先看一下目前的数据请求,看上去还是比较累。

image.png

数据请求推荐使用 ahooks ,在满足基本需求的同时还新增很多人性化配置。

我们看一个简单的 useRequest:

import React from 'react';
import { useRequest } from 'ahooks';
import Mock from 'mockjs';

function getUsername() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (Math.random() > 0.5) {
        resolve(Mock.mock('@name'));
      } else {
        reject(new Error('Failed to get username'));
      }
    }, 1000);
  });
}

export default () => {
  const { data, error, loading } = useRequest(getUsername);

  if (error) {
    return <div>{error.message}</div>;
  }
  if (loading) {
    return <div>loading...</div>;
  }
  return <div>Username: {data}</div>;
};

像 getUsername 这类接口函数,我们一般使用工具生成(例如市面上的 Swagger),不用关心,只需关注业务逻辑即可,可以看到 useRequest 已经帮我们处理了 error,loading 等状态,更多配置可查看官网。