blog icon indicating copy to clipboard operation
blog copied to clipboard

React 项目代码规范

Open yanyue404 opened this issue 5 years ago • 0 comments

项目

  • 项目目录结构清晰 Components Routes Config
  • 代码格式化符合 eslint,运行以及 pre-commit 都检测
  • 避免多层嵌套,webpack 配置别名 alias
  • utils 导入方式,按需引入
  • git commit log

组件

  • Smart 组件 vs Dumb 组件 Smart 和 Dumb 组件分开到两个不同的目录,不再在 Dumb 组件内部进行 connect,在 src/ 目录下新建两个文件夹 components/ 和 containers/:
src/
  components/
  containers/
  • 组件命名
// bad
import Footer from './Footer/Footer';

// bad
import Footer from './Footer/index';

// good
import Footer from './Footer';
  • 封装时最好提供 demo 以及 README,做好严格的类型检查(能做单元测试更好)
  • 复杂的 state 逻辑, 请抽离成 hooks 函数
// bad

function TargetComponent({ url, options }) {
  const [data, setData] = useState([]);

  useEffect(async ()=>{
    cosnt data = await fetch(url, options);
    setData(data)
  }, [])

  function handleOnUpdateData (nextOptions) {
    cosnt data = await fetch(url, nextOptions);
    setData(data)
  }

  return <OtherComponent data={data} onChange={handleOnUpdateData} />
}
// best

// 将状态逻辑抽离至 hooks 文件夹内
import useFetchData from 'src/hooks/useFetchData';

function TargetComponent({ url, options }) {
  // 复用 state 逻辑, 是 hooks 最重要的意义
  const [data, updateData] = useFetchData(url, options);

  return <OtherComponent data={data} onChange={updateData} />;
}
  • 组件抽象,好的代码复用,HOC && Hook

编码

  • 尽量使用PureComponent
  • 避免根据 props 去初始化 state
  • 为组件绑定事件处理器,使用箭头函数
  • 唯一 key 设置
  • JSX 属性名使用骆驼式风格camelCase
  • 仅在实例化生命周期中绑定 window 或 body 事件,在销毁期生命周期中解绑 window 或 body 事件
  • shouldComponentUpdate 优化 immutable?
  • 代码分片(适当情况)
const Artists = React.lazy(() => import('./Artists'));

function MyComponent() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <Artists />
      </Suspense>
    </div>
  );
}
  • 类组件编写
  1. static 开头的类属性,如 defaultProps、propTypes。
  2. 构造函数,constructor。
  3. getter/setter(还不了解的同学可以暂时忽略)。
  4. 组件生命周期。
  5. _ 开头的私有方法。
  6. 事件监听方法,handle*。
  7. render开头的方法,有时候 render() 方法里面的内容会分开到不同函数里面进行,这些函数都以 render 开头。
  8. render() 方法。
  • Hooks 的函数组件
import React, { useState, useEffect, useCallback } from 'react';

function fixDataToPlan(data) {}

function TargetComponent({ userInfo }) {
  const [loading, setLoading] = useState(false);

  useEffects(fn, [])getPhotops

  useEffects(fn, [userInfo])

  useEffects(fn)

  // 除了 handle 函数, 其他函数都不要在组件内声明, 请声明在 [3. 内部函数声明] 中
  // 因为函数组件每次重新执行, 内部函数都会重新声明, 所以要减少不必要的内部函数声明
  // function fixDataToPlan(){}

  // 6.4 被事件绑定的函数, 使用 handle 开头
  function handleOnClick(){}

  return <div>example</div>
}

// 7声明 propTypes
TargetComponent.propTypes = {
  ...
};

// 声明 mapStateToProps 函数
function mapStateToProps (state) {}

// 声明 mapDispatchToProps 函数
function mapDispatchToProps (dispatch) {}

// 导出 default 对象
export default TargetComponent;

// 导出 default 对象, 如果需要使用 HOC 处理组件, 请直接返回处理之后的组件
export default connect(mapStateToProps, mapDispatchToProps)(TargetComponent);

参考链接

yanyue404 avatar Feb 08 '20 08:02 yanyue404