Skip to the content.

Airbnb React/JSX 风格指南

React 和 JSX 的最佳实践

这个指南大部分基于现在在JavaScript中流行的标准,尽管有些约定(如: async/await 或 class 的 static 字段)根据具体情况也会被引入或者被禁止。当前这个指南不包括也不推荐任何 ECMAScript stage-3(第三阶段提案) 之前的内容。

目录

  1. 基本规则(Basic Rules)
  2. Class vs React.createClass vs stateless
  3. 混合(Mixins)
  4. 命名(Naming)
  5. 声明(Declaration)
  6. 对齐(Alignment)
  7. 引号(Quotes)
  8. 空格(Spacing)
  9. 属性(Props)
  10. 引用(Refs)
  11. 括号(Parentheses)
  12. 标签(Tags)
  13. 方法(Methods)
  14. 排序(Ordering)
  15. isMounted

Basic Rules

Class vs React.createClass vs stateless

Mixins

Why? mixins 会引入一些隐含依赖,导致命名冲突,会导致滚雪球式的复杂度。大多数情况下,mixins 都可以通过组件,高阶组件 HOC或者工具模块更好的实现。

Naming

Declaration

Alignment

Quotes

Spacing

Props

Why? 使用屏幕阅读器和键盘的人使用的键盘快捷键和键盘命令之间的不一致使得可访问性变得复杂。

  // bad
  <div accessKey="h" />

  // good
  <div />

Why? 不使用稳定杆的 ID is an anti-pattern 会对组件性能产生消极影响,并且组件状态容易出现问题。 如果数组元素可能会发生变化,我们不推荐使用下标作为key。

  // bad
  {todos.map((todo, index) =>
    <Todo
      {...todo}
      key={index}
    />
  )}

  // good
  {todos.map(todo => (
    <Todo
      {...todo}
      key={todo.id}
    />
  ))}

Why? propTypes 是一个文档形式,同时提供默认属性意味着使用者不需要假定那么多值。另外,这也意味着你的代码可以忽略类型检查。

  // bad
  function SFC({ foo, bar, children }) {
    return <div>{foo}{bar}{children}</div>;
  }
  SFC.propTypes = {
    foo: PropTypes.number.isRequired,
    bar: PropTypes.string,
    children: PropTypes.node,
  };

  // 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,
  };

例外:

  function HOC(WrappedComponent) {
    return class Proxy extends React.Component {
      Proxy.propTypes = {
        text: PropTypes.string,
        isLoading: PropTypes.bool
      };

      render() {
        return <WrappedComponent {...this.props} />
      }
    }
  }
  export default function Foo {
    const props = {
      text: '',
      isPublished: false
    }

    return (<div {...props} />);
  }

使用说明: 尽可能过滤出不需要的属性。同时用prop-type-exact去帮助避免bug。

  // bad
  render() {
    const { irrelevantProp, ...relevantProps  } = this.props;
    return <WrappedComponent {...this.props} />
  }

  // good
  render() {
    const { irrelevantProp, ...relevantProps  } = this.props;
    return <WrappedComponent {...relevantProps} />
  }

Refs

Parentheses

Tags

Methods

Ordering

  1. 可选的 static 方法
  2. constructor
  3. getChildContext
  4. componentWillMount
  5. componentDidMount
  6. componentWillReceiveProps
  7. shouldComponentUpdate
  8. componentWillUpdate
  9. componentDidUpdate
  10. componentWillUnmount
  11. clickHandlers or eventHandlers 如: onClickSubmit()onChangeDescription()
  12. getter methods for render 如: getSelectReason()getFooterContent()
  13. optional render methods 如: renderNavigation()renderProfilePicture()
  14. render
  1. displayName
  2. propTypes
  3. contextTypes
  4. childContextTypes
  5. mixins
  6. statics
  7. defaultProps
  8. getDefaultProps
  9. getInitialState
  10. getChildContext
  11. componentWillMount
  12. componentDidMount
  13. componentWillReceiveProps
  14. shouldComponentUpdate
  15. componentWillUpdate
  16. componentDidUpdate
  17. componentWillUnmount
  18. clickHandlers or eventHandlers 如: onClickSubmit()onChangeDescription()
  19. getter methods for render 如: getSelectReason()getFooterContent()
  20. optional render methods 如: renderNavigation()renderProfilePicture()
  21. render

isMounted

Why? [isMounted 是反模式][anti-pattern], 这个在 ES6 class 里不允许的,而且即将被官方废弃。

Translation

JSX/REACT 风格指南的其他语言翻译版

⬆ back to top