1. 程式人生 > 實用技巧 >React 程式碼規範

React 程式碼規範

1、基礎規則

一個檔案宣告一個元件:儘管可以在一個檔案中宣告多個react元件,但是最好不要這樣做;推薦一個檔案宣告一個react元件,並只匯出一個元件;

使用jsX 表示式:不要使用 React.createElement 的寫法;

函式元件和 class 類元件的使用場景:如果定義的元件不需要 props 和 state ,建議將元件定義成函式元件,否則定義成 class 類元件。

2、元件宣告

(1)元件名稱和定義該元件的檔名稱建議要保持一致;

推薦:

import Footer from './Footer';

不推薦:

import Footer from './Footer/index';

(2)不要使用 displayName 屬性來定義元件的名稱,應該在 class 或者 function 關鍵字後面直接宣告元件的名稱。

推薦:

export default class MyComponent extends React.Component {
}

不推薦:

export default React.Component({
  displayName: 'MyComponent',
});

3、React 中的命名

元件名稱:推薦使用大駝峰命名;

屬性名稱:React DOM 使用小駝峰命令來定義屬性的名稱,而不使用html屬性名稱的命名約定;

style 樣式屬性:

採用小駝峰命名屬性的JavaScript物件;

推薦:

// 元件名稱
MyComponent
// 屬性名稱
onClick
// 樣式屬性
backgroundColor

4、jsX 寫法注意

4.1、標籤

(1)當標籤沒有子元素的時候,始終使用自閉合的標籤 。

推薦:

// Good
<Component />

不推薦:

<Component></Component>

(2)如果標籤有多行屬性,關閉標籤要另起一行 。

推薦:

<Component
  bar="bar"
  baz="baz" 
/>

不推薦:

<Component
  bar="bar"
  baz="baz" />

(3)在自閉標籤之前留一個空格。

推薦:

<Foo />

不推薦:

<Foo/>

<Foo                 />

<Foo
 />

(4)當元件跨行時,要用括號包裹 JSX 標籤。

推薦:

  render() {
    return (
      <MyComponent className="long body" foo="bar">
        <MyChild />
      </MyComponent>
    );
  }

不推薦:

  render() {
    return <MyComponent className="long body" foo="bar">
             <MyChild />
           </MyComponent>;
  }

4.2、對齊

JSX語法使用下列的對齊方式 :

// 推薦
<Foo
  superLongParam="bar"
  anotherSuperLongParam="baz"
/>

// 如果元件的屬性可以放在一行(一個屬性時)就保持在當前一行中
<Foo bar="bar" />

// 多行屬性採用縮排
<Foo
  superLongParam="bar"
  anotherSuperLongParam="baz"
>
  <Quux />
</Foo>

// 不推薦
<Foo superLongParam="bar"
     anotherSuperLongParam="baz" />

4.3、引號

JSX 的屬性都採用雙引號,其他的 JS 都使用單引號 ,因為 JSX 屬性 不能包含轉義的引號, 所以當輸入 "don't" 這類的縮寫的時候用雙引號會更方便。

推薦:

<Foo bar="bar" />

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

不推薦:

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

5、樣式寫法

React 中樣式可以使用 style 行內樣式,也可以使用 className 屬性來引用外部css樣式表中定義的css類,我們推薦使用 className 來定義樣式。並且推薦使用 SCSS 來替換傳統的 CSS 寫法,具體 SCSS 提高效率的寫法可以參照先前總結的文章。

6、defaultProps 使用靜態屬性定義

defaultProps 推薦使用靜態屬性定義,不推薦在 class 外進行定義。

推薦:

class Example extends React.Component {
  static defaultProps = {
    name: 'stranger'
  }

  render() {
   // ...
  }
}

不推薦:

class Example extends React.Component {
  render() {
    // ...
  }
}

Example.propTypes = {
  name: PropTypes.string
};

7、key 屬性設定

key 幫助 React 識別哪些元素改變了,比如被新增或刪除。因此你應當給陣列中的每一個元素賦予一個確定的標識。 當元素沒有確定 id 的時候,萬不得已你可以使用元素索引 index 作為 key,但是要主要如果列表專案的順序可能會變化,如果使用索引來用作 key 值,因為這樣做會導致效能變差,還可能引起元件狀態的問題。

推薦:

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

不推薦:

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

8、為元件繫結事件處理器

React 為元件繫結事件處理器提供 4 種方法,有 public class fields語法、建構函式中進行繫結、在回撥中使用箭頭函式、使用 Function.prototype.bind 進行繫結,我們推薦使用 public class fields 語法,在不滿足需求情況下使用箭頭函式的寫法(傳遞引數給事件處理器)。

推薦:

 handleClick = () => {
    console.log('this is:', this);
 }
 <button onClick={this.handleClick}> Click me </button>

不推薦:

 constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
 }
 handleClick(){
    console.log('this is:', this);
 }
 <button onClick={this.handleClick}> Click me </button>

9、State

9.1、不要直接修改 state

除了 state 初始化外,其它地方修改 state,需要使用 setState( ) 方法,否則如果直接賦值,則不會重新渲染元件。

推薦:

this.setState({comment: 'Hello'});

不推薦:

this.state.comment = 'hello';

9.2、State 的更新可能是非同步的

出於效能考慮,React 可能會把多個 setState( ) 呼叫合併成一個呼叫;因為this.props和this.state可能會非同步更新,所以這種場景下需要讓 setState() 接收一個函式而不是一個物件 。

推薦:

this.setState((state, props) => ({
  counter: state.counter + props.increment
}));

不推薦:

this.setState({
  counter: this.state.counter + this.props.increment,
});

10、元件的程式碼順序

元件應該有嚴格的程式碼順序,這樣有利於程式碼維護,我們推薦每個元件中的程式碼順序一致性。

class Example extends Component {
    // 靜態屬性
    static defaultProps = {}

    // 建構函式
    constructor(props) {
        super(props);
        this.stae={}
    }

    // 宣告週期鉤子函式
    // 按照它們執行的順序
    // 1. componentWillMount
    // 2. componentWillReceiveProps
    // 3. shouldComponentUpdate
    // 4. componentDidMount
    // 5. componentDidUpdate
    // 6. componentWillUnmount
    componentDidMount() { ... }

    // 事件函式/普通函式
    handleClick = (e) => { ... }

    // 最後,render 方法
    render() { ... }
}

11、使用高階元件

使用高階元件解決橫切關注點問題,而不是使用 mixins ,mixins 導致的相關問題可以參照文件;

12、避免不必要 render 的寫法

shouldComponentUpdate 鉤子函式和 React.PureComponent 類都是用來當 state 和 props 變化時,避免不必要的 render 的方法。shouldComponentUpdate 鉤子函式需要自己手動實現淺比較的邏輯,React.PureComponent 類則預設對 props 和 state 進行淺層比較,並減少了跳過必要更新的可能性。 我們推薦使用 React.PureComponent 避免不要的 render。

13、狀態提升

如果多個元件需要反映相同的變化資料,建議將共享狀態提升到最近的共同父元件中去;從而依靠自上而下的資料流,而不是嘗試在不同元件間同步 state。

14、推薦使用 Context

如果某個屬性在元件樹的不同層級的元件之間需要用到,我們應該使用 Context 提供在元件之間共享此屬性的方式,而不不是顯式地通過元件樹的逐層傳遞 props。

15、Refs 寫法

Refs 提供了一種方式,允許我們訪問 DOM 節點或在 render 方法中建立的 React 元素 。我們推薦使用createRef API 的方式或者回撥函式的方式使用 Refs ,而不是使用this.refs.textInput這種過時的方式訪問 refs ,因為它存在一些問題。

16、路由載入

建議使用路由懶載入當前使用者所需要的內容,這樣能夠顯著地提高你的應用效能。儘管並沒有減少應用整體的程式碼體積,但你可以避免載入使用者永遠不需要的程式碼,並在初始載入的時候減少所需載入的程式碼量。

推薦:

const OtherComponent = React.lazy(() => import('./OtherComponent'));

不推薦:

import OtherComponent from './OtherComponent';

豌豆資源搜尋網站https://55wd.com 電腦刺繡繡花廠 ttp://www.szhdn.com

17、AJAX 發起請求的時機

推薦在 componentDidMount這個生命週期函式中發起 AJAX 請求。這樣做你可以拿到 AJAX 請求返回的資料並通過 setState 來更新元件。