組件
React提供React.Component,我們可以透過使用組件,拆分 UI 為可以重複使用的獨立部分。React.Component是一個抽象的 base class。我們甚少直接運用React.Component,通常是透過創建一個子類,並使用render()方法。
例子:
class Greeting extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}如果你不選擇使用 ES6,你可以使用模組create-react-class。你可以參考React Without ES6。
下面這一段和 ES6 的寫法效果一樣:
var createReactClass = require("create-react-class");
var Greeting = createReactClass({
render: function () {
return <h1>Hello, {this.props.name}</h1>;
},
});組件生命週期
每一個組件都會有幾個生命週期的方法,你可以在程序運行的指定時間,透過覆蓋他們來運行特定代碼。對於這些方法,我們會用will-來表示它會在某些事情發生之前的一刻被調用,而did-則是表示它會在某些事情發生之後的一刻被調用。本文會細說加載組件中發生了什麼事情。
加載 (Mounting)
constructor()componentWillMount()render()componentDidMount()
更新 (Updating)
當 props 或者 state 更新的時候,下面這些方法會被調用:
- componentWillReceiveProps()
- shouldComponentUpdate()
- componentWillUpdate()
- render()
- componentDidUpdate()
斷開連接 (Unmounting)
當組件脫離 DOM 的時候,下面這個方法回被調用:
- componentWillUnmount()
其他內置方法
- setState()
- forceUpdate()
我們會在下文討論一下 React 是如何加載組件。
{% img /img/react-mount.svg 300 auto React LifeCycle Mount %}
constructor()
constructor(props);在 React 加載組件之前,它會調用constructor。你可以在constructor中去賦予組件的初始state。如果你使用props創造初始state的話,這也是可以接受的。這會很有效地fork組件的props,然後賦予初始state的值。
有效的constructor例子:
constructor(props) {
super(props);
this.state = {
color: props.initialColor
};
}注意事項
- 如果你不需要賦予初始
state,你不需要在 React 的組件中植入constructor。 - 當你使用在
React.Component的子類中加載constructor()方法時,你應該第一時間調用super(props),而不是在任何 statement 之後。不然,我們獲取this.props值的時候,它會是undefined。 - 在一些類似上面的例子,
state未必會及時與任何的props更新。如果你需要同步state的話,你其實是想要lift the state up。
componentWillMount()
componentWillMount();它會在組件render()之前執行一次,然後不能再執行。如果在這裡定義了setState方法,頁面只會在加載之前更新一次,不會重複渲染。React 官方推薦使用constructor()代替這個方法。
render()
React.Component必須有這個方法,即使你返回null,或者false。當你返回null,或者false的時候,ReactDOM.findDOMNode(this) 會返回null。
當它被調用的時候,它會檢查this.props和this.state,然後返回一個單獨的 React 元素。這個元素會是一個純正的DOM組件,例如
注意事項
render()方法應該是pure:它不會改寫任何組件的state。每一次調用它都會返回同樣的結果。它不會直接接觸到瀏覽器層面。- 如果你需要接觸到瀏覽器層面,你應該在
componentDidMount()或者其他生命週期方法中接觸瀏覽器。 - 保持
render()方法 pure 來讓組件更加容易被人理解。
componentDidMount()
componentDidMount();它會在組件加載之後執行一次。如果你的初始程序需要 DOM nodes,你應該在這裡寫。如果你需要從其他地方加載資料,這裡也是一個不錯的地方去執行網絡請求。如果在這裡定義了setState方法,會觸發重複渲染。
測試代碼
class Greeting extends React.Component {
_log(method, args) {
console.log(method, args);
}
constructor(props) {
super(props);
console.log("constructor", props);
}
render() {
this._log("render", this.props.name);
return <h1>Hello, {this.props.name}</h1>;
}
componentWillMount() {
this._log("componentWillMount");
}
componentDidMount() {
this._log("componentDidMount");
}
}
ReactDOM.render(<Greeting name="Calpa" />, document.getElementById("app"));Console Output:
"constructor" Object {
name: "Calpa"
}
"componentWillMount" undefined
"render" "Calpa"
"componentDidMount" undefined你可以在CodePen中獲取,並測試這段代碼。
不知道拿哪一張當封面好。。。
如果你有 AI 專案、網站開發或技術整合需求,歡迎來信交流: partner@calpa.me
歡迎訂閱 Calpa 的頻道,一同將想像力化為可能: