Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React组件规范 #15

Open
Jeffersondyj opened this issue Jun 15, 2018 · 0 comments
Open

React组件规范 #15

Jeffersondyj opened this issue Jun 15, 2018 · 0 comments

Comments

@Jeffersondyj
Copy link
Owner

前言

基于ES6的React组件规范
文中可能会出现:MUST SHOULD MAY 表示肯定,语气强到弱
MAY NOT SHOULD NOT MUST NOT 表示否定,语气弱到强

命名&声明

文件名:MUST 使用大驼峰,如 MyComponent.js;
组件命名:组件名称 MUST 和文件名一致,如 MyComponent.js 里的组件名 MUST 是 MyComponent;一个目录的根组件 SHOULD 使用 index.js 命名,MUST 以目录名称作为组件名称;

// bad 
export default React.createClass({
    displayName: 'ReservationCard' 
});

// good 
const ReservationCard = React.createClass({
});

export default ReservationCard;

引号引用

// bad
<Foo bar='bar' />
// good
<Foo bar="bar" />

// bad
<Foo style={{ left: "20px" }} />
// good
<Foo style={{ left: '20px' }} />

属性书写

属性较少时 MAY 行内排列;
属性较多时 MUST 每行一个属性,闭合标签单独成行。

// bad
<input type="text" value={this.state.newDinosaurName} onChange={this.inputHandler.bind(this, 'newDinosaurName')} />
// bad
<input type="text" value={this.state.newDinosaurName}
   onChange={this.inputHandler.bind(this, 'newDinosaurName')} />

// good
<input
    type="text"
    value={this.state.newDinosaurName}
    onChange={this.inputHandler.bind(this, 'newDinosaurName')}
/>

方法

SHOULD NOT 使用下划线前缀命名 React 组件的方法;
MUST 按照生命周期组顺序织组件的方法、属性;
方法之间 MUST 空一行;
render MUST 始终放在最后;
自定义方法 SHOULD 放在 React API 方法之后,render之前。

// React 组件中按照以下顺序组织代码
class extends React.Component {
    getDefaultProps() {
    }

    getInitialState() {
    }

    componentWillMount() {
    }

    componentDidMount() {
        // do something: add DOM event listener, etc.
    }

    componentWillReceiveProps() {
    }

    shouldComponentUpdate() {
    }

    componentWillUpdate() {
    }

    componentDidUpdate() {
    }

    componentWillUnmount() {
        // do something: remove DOM event listener. etc.
    }

    // getter methods for render like getSelectReason() or getFooterContent()

    // Optional render methods like renderNavigation() or renderProfilePicture()

    render() {
        // ...
    }
}

render

render方法里面 SHOULD 以<开头,不应该存在if else分支,视情况返回不同的JSX。相同的组件 SHOULD 返回相同的顶级元素容器。

// bad
render() {
    if (this.state.a) {
        return <strong>222</strong>
    } else {
        return <div>222</div>
    }
}

ref

ref SHOULD NOT 用字符串形式,因为字符串形式的ref会自始至终将字符串放在refs对象中,会有泄露的问题。

// bad
<Foo
    ref="myRef"
/>

// ok
<Foo
    ref={(ref) => { this.myRef = ref; }}
/>

上面的方法之所以是ok,而不是good,是因为我们在查看组件时,很难察觉到你在JSX里偷偷为组件添加了一个新属性。组件所有用到的属性,应该都能在constructor或defaultProps中找到。

setState死循环

MUST NOT 在componentWillUpdate/componentDidUpdate/render中执行setState,可能导致死循环。

bind

SHOULD NOT 在JSX中使用bind方法绑定组件实例,可能导致性能问题。

// bad
class extends React.Component {
    onClickDiv() {
    }

    render() {
        return <div onClick={this.onClickDiv.bind(this)} />;
    }
}

// good
class extends React.Component {
    constructor(props) {
        super(props);
        this.onClickDiv = this.onClickDiv.bind(this);
    }

    onClickDiv() {
    }

    render() {
        return <div onClick={this.onClickDiv} />;
    }
}

其他

SHOULD NOT 使用cloneElement,createElement。
cloneElement可能会导致_owner丢失。_owner丢失会导致ref失效。

MAY NOT 使用createClass,mixin,PropTypes(它们已经被移出核心库,被逐渐边缘化)。

单个组件里面的DOM循环逻辑 MUST NOT 超过3层嵌套。
整个系统里面的组件的循环逻辑 MUST NOT 超过9层嵌套。

先写到这里,后续慢慢补充。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant