1. 命名JSX文件为.jsx或.js文件,注意保持命名统一,.jsx与.js文件不同时存在。
  2. 使用PascalCase作为组件名。
  3. 令文件名与所包含的React Component名字相同。
  4. 使用ES Class声明组件来创建一个React Component。
  5. 只包含一个React Component在一个JSX文件中。
  6. 使用JSX语法来生成组件的DOM片段。
  7. 书写propTypes,规定每个可接受属性的类型,并对propTypes加以注释说明。
    对象类型监测建议: PropTypes.objectOf(PropTypes.any)
    数组类型监测建议: PropTypes.arrayOf(PropTypes.any)
  8. 使用camalCase来命名props。必须将bind handler到this的动作放到构造函数中(this.onClickDiv.bind(this)性能优化问题,不要放在生命周期运行阶段jsx中),其中可用箭头函数的方式绑定this。
  9. 在props中存放所有外部导入的配置,包括显示控制参数、显示数据源、当前值(如果是input类型组件)、回调方法等。state相同时,对于一个特定的props,对应的组件展现结果唯一。
  10. 在state中存放组件运行期的状态,如输入框是否通过了校验、鼠标是否悬浮在按钮上等。props相同时,对于一组特定的state,对应的组件展现效果唯一。
  11. 不应该在state中存在通过props运算来的属性
  12. 仅在实例化生命周期中绑定window或body事件。
  13. 在销毁期生命周期中解绑window或body事件。
  14. 必须将所有UI组件实现为[Pure Renderer] (对React.pureComponent)。
  15. 可以提供与组件内部数据结构紧密相关的操作方法。这些方法可以实现为一个纯函数,即只依赖其所有的参数来得到其结果。这些方法可以放在组件的static域中。
  16. 不允许在运行期生命周期中声明表达式函数。bind函数也不允许。
render() { //Bad
 var cleverFunction = function () {}; 
  // ... 
}

{ //Good
 cleverFunction() {}, 
 render() { 
   // just use this.cleverFunction 
 } 
}



必须只能通过以下2种方法设置组件内部状态:

  • 通过父组件的render方法,改变子组件的props。
  • 通过子组件的setState方法。

antd组件实现及element组件实现风格

  • 良好的组件 API
  • 总是关注于组件本身的目的
  • 拒绝定制代码。如果你在一个通用的组件内部编写特定需求的代码,那么代表这个组件的 API 不够通用,或者你可能需要一个新的组件来应对该需求
  • 检查所有的 props 是否有缺失的,如果有提一个 issue 或是完善这个组件
  • 检查所有的事件。子组件向父组件通信一般是通过事件来实现的,但是大多数的开发者更多的关注于 props 从忽视了这点。
  • Props向下传递,事件向上传递!
  • 当遇到 props 和 events 难以实现的功能时,通过Refs 来实现。
  • 当需要操作 DOM 无法通过指令来做的时候可使用 Refs 而不是 JQuery , document.getElement* , document.queryElement 。

下面以antd-design和element-react组件card对比两中UI组件实现风格、

antd-design(card)




elementUI 新增列 element 列表组件_element子组件中的校验


element-react(card)


elementUI 新增列 element 列表组件_element子组件中的校验_02


我们期待的组件书写方式如下:


import React,{PureComponent} from 'react';
import classnames from 'classnames';
import PropTypes from 'prop-types';

export default class Card extends PureComponent {
  static defaultProps = {
    prefixCls:'ko-card',
    className:'',
    title:'title',
    extra:'',
    loading:false,
    bordered:true,
    bodyStyle: { padding: '20px' },
    other:{},
  }
  static propTypes = {
    prefixCls:PropTypes.string,
    className:PropTypes.string,
    title:PropTypes.any,
    extra:PropTypes.any,
    loading:PropTypes.bool,
    bordered:PropTypes.bool,
    header: PropTypes.node,
    bodyStyle: PropTypes.objectOf(PropTypes.any),
    other:PropTypes.objectOf(PropTypes.any)
  }

  render(){
    let { prefixCls,className,children,bodyStyle,title,extra, loading, bordered, ...other } = this.props;
    const classString = classnames({
      [prefixCls]: true,
      [className]: !!className,
      [`${prefixCls}-loading`]: loading,
      [`${prefixCls}-bordered`]: bordered,
    });
    if (loading) {
      children = (
        <div>
          <p>████████████████████████</p>
          <p>██████ ███████████████████</p>
          <p>██████████████ ██████████</p>
          <p>█████ ██████ █████████████</p>
          <p>███████████ ██████████ ███</p>
        </div>
      );
    }
    return (
      <div {...other } className={classString}>
        {
          title && <div className={`${prefixCls}__header`}>{ title }</div>
        }
        {
          extra ? <div className={`${prefixCls}-extra`}>{extra}</div> : null
        }
        <div className={`${prefixCls}__body`} style={ bodyStyle }>
          { children }
        </div>
      </div>
    )
  }
}


以上为react组件开发编码过程中需要注意及避免的地方,养成良好的开发习惯,避免重复的搬砖,赶紧从编写高可用的组件开始吧。