React 代码规范

2020/04/02 16:51:22

基本规范

  • 每个文件只包含的一个 React 组件:
    • 联系紧密的组件可以使用「命名空间」的形式;
    • 每个文件中可包含多个纯函数组件。
  • 始终使用 JSX 语法,不要使用 React.createElement 创建 ReactElement,以提高编写速度、可读性、可维护性(没有 JSX 转换的特殊场景例外,如在 console 中测试组件)。

文件规范

  • 组件文件使用一致的.js.jsx后缀。所有组件文件的后缀名从.js.jsx中任选其一。不应在项目中出现部分组件为.js文件,部分为.jsx的情况。

  • 每个存放组件的目录使用一个index.js/index.jsx以命名导出的形式暴露所有组件。同目录内的组件相互引用使用import Foo from './Foo';进行。引用其它目录的组件使用import {Foo} from '../component';进行。

命名规范

  • 文件名:使用大驼峰命名法(PascalCase),如 MyComponent.jsx;

  • 组件命名:组件名称和文件名一致,如 MyComponent.jsx 里的组件名应该是 MyComponent;一个目录的根组件使用 index.jsx 命名,以目录名称作为组件名称;

  • 引用命名:React 组件使用大驼峰命名法(PascalCase);

  • 高阶组件使用camelCase命名。高阶组件事实上并非一个组件,而是一个“生成组件类型”的函数,因此遵守JavaScript函数命名的规范,使用camelCase命名。

  • 使用onXxx形式作为props中用于回调的属性名称。使用统一的命名规则用以区分props中回调和非回调部分的属性,在JSX上可以清晰地看到一个组件向上和向下的逻辑交互。

  • 使用withXxx或xxxable形式的词作为高阶组件的名称。高阶组件是为组件添加行为和功能的函数,因此使用如上形式的词有助于对其功能进行理解。

带命名空间的组件

  • 如果一个组件有许多关联子组件,可以以该组件作为命名空间编写、调用子组件。
class Form extends React.Component {  
  // ...
}

class Row extends React.Component {}
class Label extends React.Component {}
class Input extends React.Component {}

Form.Row = Row;
Form.Label = Label;
Form.Input = Input;

export default Form;

// refence Form component
import Form from './Form';

const App = (
  <Form>
    <Form.Row>
      <Form.Label />
      <Form.Input />
    </Form.Row>
  </Form>
);

属性

属性设置

  • 在组件行内设置属性(以便 propTypes 校验),不要在外部改变属性的值;
  • 属性较多使用 {…this.props} 语法;
// good
const props = {};
props.foo = x;
props.bar = y;
const component = <Component {...props} />;
  • 属性值明确为 true 时,省略值。

属性对齐方式

  • 属性较少时可以行内排列;
  • 属性较多时每行一个属性,闭合标签单独成行。
// bad - too long
<input type="text" value={this.state.newDinosaurName} onChange={this.inputHandler.bind(this, 'newDinosaurName')} />  

// bad - aligning attributes after the tag
<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')}
 />

属性空格

  • 属性 = 前后不要添加空格
  • JSX 中的花括号前后不要添加空格。
// bad
<Foo bar={ baz } foo = "bar" />

// good
<Foo bar={baz} foo="bar" />

// good { left: '20px' } 为一个对象
<Foo style={{ left: '20px' }} />

propTypes 及默认值

  • 组件属性都应该在 propTypes 中声明类型;
  • 始终明确指定非必选属性的默认值。
// bad
function SFC({ foo, bar, children }) {
  return <div>{foo}{bar}{children}</div>;
}


// good
function SFC({ foo, bar, children }) {
  return <div>{foo}{bar}{children}</div>;
}

SFC.propTypes = {
  foo: PropTypes.number.isRequired,
  bar: PropTypes.string,
  children: PropTypes.node,
};

SFC.defaultProps = {
  bar: '',
  children: null,
};

引号

  • JSX 属性使用双引号 "
  • JS 使用单引号 '

() 使用

  • 多行的 JSX 使用 () 包裹,有组件嵌套时使用多行模式;
// bad
 return (<div><ComponentOne /><ComponentTwo /></div>);

 // good
 var multilineJsx = (  
   <header>
     <Logo />
     <Nav />
   </header>
 );

 // good
 return (
   <div>
     <ComponentOne />
     <ComponentTwo />
   </div>
);
  • 单行 JSX 省略 ()

自闭合标签

  • 自闭合所有没有子组件的标签;
  • 自闭合标签 / 前留一个空格
// bad
<Logo></Logo>

// very bad
<Foo                 />

// bad
<Foo
 />

// good
<Logo />

方法

  • 事件函数用 public class fields
// good
class Foo extends React.Component {
  handleClick = () => {
    this.setState({ xxx: aaa })
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        Click me
      </button>
    )
  }
}

// bad
class Foo extends React.Component {
  handleClick () {
    this.setState({ xxx: aaa })
  }

  render() {
    return (
      <button onClick={this.handleClick.bind(this)}>
        Click me
      </button>
    )
  }
}
  • 事件处理方法以 handle 开头,如 handleClick() {},用 on 的作为回调做区分

组件代码组织

  • 按照生命周期顺序组织组件的属性、方法;
  • 方法(属性)之间空一行;
  • render() 方法始终放在最后;
  • 自定义方法 React API 方法之后、render() 之前;
  • class extends React.Component 顺序:
    1. static 属性
    2. static 方法
    3. constructor
    4. getChildContext
    5. componentWillMount
    6. componentDidMount
    7. componentWillReceiveProps
    8. shouldComponentUpdate
    9. componentWillUpdate
    10. componentDidUpdate
    11. componentWillUnmount
    12. 点击处理函数或者其他事件处理函数,如 onClickSubmit()onChangeDescription()
    13. render 的 getter 方法,如 getSelectReason()getFooterContent()
    14. 可选的 render 方法,如 renderNavigation()renderProfilePicture()
    15. render
  • 定义 propTypes, defaultProps, contextTypes

代码校验工具

参考:https://github.com/minwe/style-guide/blob/master/React.js.md

参考:JasonBoy/javascript


Profile picture

桃翁 所写,你可以在 GitHub 上找到我