如何編寫一個React元件

Capricorn_PJ發表於2018-09-10

如何編寫一個React元件

在React的世界裡,通常是用class來宣告一個元件的,它必須繼承自React.Component
例如下面的程式碼:

// MyFirstComponent.jsx
class MyFirstComponent extends React.Component {
  state = {
    text: "Hello React"
  };

  /** 元件生命週期鉤子函式:在元件掛載完成後立即被呼叫 */
  componentDidMount() {
    alert("元件掛載完成!");
  }

  render() {
    return (
      <div>{this.state.text}, I am {this.props.author}!</div>
    )
  }
}

export default MyFirstComponent;
// index.js
import MyFirstComponent from "MyFirstComponent";

/** 渲染結果:<div>Hello React, I am Shaye!</div> */
ReactDOM.render(<MyFirstComponent author="Shaye"></MyFirstComponent>, document.getElementById("app"));

以上就是一個常規的React元件編寫方式,不過我們還可以通過觀察上面的程式碼,發現幾個有趣的地方:

  1. MyFirstComponent中有一個函式componentDidMount是元件生命週期鉤子函式。實際上React為元件設計了一系列的生命週期鉤子函式
  2. MyFirstComponent中有一個特別的函式render(),這個函式把類似html的模板內容jsx作為返回值。這是一個必須定義的函式,否則React將丟擲錯誤
  3. jsx乍看之下像是一種模板引擎,實際上是一種JavaScript的語法擴充套件,它的核心理念就是著名的all in js,它完全是在JavaScript內部實現的,它和傳統的模板引擎一樣,也可以繫結js表示式
  4. jsx繫結的資料可以很明顯地看出來自兩個物件:this.statethis.propsthis.stateMyFirstComponent內部自定義的元件狀態;this.props是外部憑藉標籤屬性的形式傳進MyFirstComponent內部的資料,類似於函式的傳參;

總結來說,當你掌握了   元件生命週期   JSX   元件狀態state   元件屬性props   ,你就知道該如何編寫React元件了。

元件生命週期

官方文件已經有非常詳盡的介紹,這裡不再贅述,請點選這裡檢視元件生命週期的官方文件。

JSX

你可以任意地在JSX當中使用javaScript表示式,在JSX當中的表示式要包含在大括號裡。
例如下面的程式碼:

<div className={this.state.clname} style={{ fontSize: "20px" }}>{this.state.content} forever</div>

JSX裡的React元素,比如div,最終都會被編譯器轉譯,被某些特定函式處理變成一個輕量的javascript object。比如上面提到的元素div最終會變成如下的object

// 注意: 以下示例是簡化過的(不代表在 React 原始碼中是這樣)
const divElement = {
  type: "div",
  props: {
    // this.state.clname的值
    className: "love",
    style: {
      fontSize: "20px"
    },
    // "you"為this.state.content的值
    children: ["you", "forever"]
  }
}

React就是通過讀取這些物件來操作DOM並保持資料內容一致。所以,實際上你依然在寫js。所以,classstyle必須使用在js中的寫法
比如:class => className
再比如:font-size: 20px; => { fontSize: "20px" }

特別地,React元素的屬性仍然可以像原生html一樣使用引號來定義以字串為值的屬性,例如:className="my-claname"

除了以上所提,JSX的事件繫結與原生html也有一些語法上的不同:

  • React的事件命名採用駝峰式寫法,而不是小寫。
  • React事件繫結的必須是一個函式物件,不能是字串。

程式碼示例:

<div onClick={this.handleClick}>我是一個按鈕</div>

// 也可以向事件回撥函式傳遞引數
<div onClick={(params) => this.handleClick(params)}>我是一個按鈕</div>

元件狀態state

state是私有的,完全受控於當前元件。既然是狀態,那麼就會有更新的需求,如何更新呢?
程式碼示例:

// 對`this.state`或者它的屬性直接`=`賦值,將永遠不會觸發元件渲染,必須使用`setState()`

// 在元件的生命週期鉤子函式中呼叫this.setState()
componentDidMount() {
  this.setState({
    content: "lalalala"
  })
}

// 在元件的自定義函式中呼叫this.setState()
handleClick = () => {
  this.setState({
    content: "uauauaua"
  })
}

setState()是React中唯一一個動態更新元件的途徑,當它被呼叫之後,自身元件以它的所有子元件都將觸發重渲染
特別地,state同樣也可以作為屬性傳遞給子元件;
setState()詳細文件

元件屬性props

props是父元件傳遞下來的資料,一般是來自父元件的state或者元件的其他成員變數。並且,props是隻讀的,元件永遠無法修改自己的props。只有在父元件呼叫setState()之後才能使子元件的屬性發生變化並重新渲染。
props只能從上往下傳,元件也只能修改自身私有的state,意味著整個應用的資料流只能是自上往下的單向資料流

總結

   元件生命週期   JSX   元件狀態state   元件屬性props    再加上一個自上而下的單向資料流,這些便是React元件最基本的特點了吧!

相關文章