- 命名JSX文件为.jsx或.js文件,注意保持命名统一,.jsx与.js文件不同时存在。
- 使用PascalCase作为组件名。
- 令文件名与所包含的React Component名字相同。
- 使用ES Class声明组件来创建一个React Component。
- 只包含一个React Component在一个JSX文件中。
- 使用JSX语法来生成组件的DOM片段。
- 书写propTypes,规定每个可接受属性的类型,并对propTypes加以注释说明。
对象类型监测建议: PropTypes.objectOf(PropTypes.any)
数组类型监测建议: PropTypes.arrayOf(PropTypes.any) - 使用camalCase来命名props。必须将bind handler到this的动作放到构造函数中(this.onClickDiv.bind(this)性能优化问题,不要放在生命周期运行阶段jsx中),其中可用箭头函数的方式绑定this。
- 在props中存放所有外部导入的配置,包括显示控制参数、显示数据源、当前值(如果是input类型组件)、回调方法等。state相同时,对于一个特定的props,对应的组件展现结果唯一。
- 在state中存放组件运行期的状态,如输入框是否通过了校验、鼠标是否悬浮在按钮上等。props相同时,对于一组特定的state,对应的组件展现效果唯一。
- 不应该在state中存在通过props运算来的属性
- 仅在实例化生命周期中绑定window或body事件。
- 在销毁期生命周期中解绑window或body事件。
- 必须将所有UI组件实现为[Pure Renderer] (对React.pureComponent)。
- 可以提供与组件内部数据结构紧密相关的操作方法。这些方法可以实现为一个纯函数,即只依赖其所有的参数来得到其结果。这些方法可以放在组件的static域中。
- 不允许在运行期生命周期中声明表达式函数。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)
element-react(card)
我们期待的组件书写方式如下:
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组件开发编码过程中需要注意及避免的地方,养成良好的开发习惯,避免重复的搬砖,赶紧从编写高可用的组件开始吧。