[react] 元件(component)
未閱讀:Writing Resilient Components @ OverReacted
建立元件(Component)
React 中的元件(component)是一個小而可重複使用的程式碼,每一個元件都必須從 Component
這個類別(class)而來,component class 就像是一個可以用來建立許多不同元件的工廠。
在 render()
方法中,記得要使用 return
回傳樣版:
import React from 'react';
import ReactDOM from 'react-dom';
class MyComponentClass extends React.Component {
render() {
return <h1>Hello world</h1>;
}
}
const root = ReactDOM.createRoot(document.getElementById('app'));
root.render(<MyComponentClass />);
轉譯多行的樣版(template)
當在 React Component 中要轉譯多行的樣版時,要使用括號 ()
把多行的程式碼包起來:
import React from 'react';
import ReactDOM from 'react-dom';
class QuoteMaker extends React.Component {
render() {
return (
<blockquote>
<p>What is important now is to recover our senses.</p>
<cite>
<a target="_blank" href="https://en.wikipedia.org/wiki/Susan_Sontag">
Susan Sontag
</a>
</cite>
</blockquote>
);
}
}
const root = ReactDOM.createRoot(document.getElementById('app'));
root.render(<QuoteMaker />);
Stateful 或 Stateless
在 React 中,Stateful 指的是帶有 state
屬性的元件;而 stateless 則是指任何不帶有 state
屬性的元件。
在 React 元件中,props
只可以透過自己以外的其他元件來修改它,絕不應該更新它自己的 this.props
;而 state
則相反,只應該透過自己更新 this.state
,其他的元件都不應該更改自己以外其他的元件。
States
在 React 元件中有兩種方式可以存取動態的資料,分別是 props
和 state
。與 props
不同的地方在於,state
不是透過外部傳進來的,而是由一個元件決定它自己內部 state
。
定義 States
我們可以在 Class(類別)的建構式(constructor)中,透過 this.state
來定義 state 的內容:
class Example extends React.Component {
constructor(props) {
super(props);
this.state = { mood: 'decent' };
}
render() {
return <h1>I'm feeling {this.state.mood}!</h1>;
}
}
<Example />;
使用 States
keywords: this.state
在元件中,只需要透過 this.state.name-of-property
就可以取得 state 的內容。
更新 State
keywords: this.setState
使用 this.setState
可以更新資料狀態(state),這個方法會將新的物件合併(merge)進原本的物件,因此資料狀態中沒有被更新到的部分,則會保留原有的狀態。
每當呼叫 this.setState()
時,this.setState()
會在資料狀態改變時,自動呼叫 .render()
,進而導致畫面重新轉譯。
簡單來說,在
this.setState()
之後,會自動呼叫.render()
,因此不能在 render 函式中使用this.setState()
,因為這將導致無窮迴圈。
需要留意的是,在 <button onClick={this.toggleMood}>
中,它會尚失其原本的 this
所指稱的對象,因此需要在 constructor 中先使用 this.toggleMood = this.toggleMood.bind(this);
把指稱到的 this
綁定好:
import React from 'react';
import ReactDOM from 'react-dom';
class Mood extends React.Component {
constructor(props) {
super(props);
this.state = { mood: 'good' };
// 這段是必要的,如果沒有這樣寫的話, toggleMood 在 onClick 的 callback 執行時,
// this 會變成 Window 物件,而不是原本的 Mood 這個類別。
this.toggleMood = this.toggleMood.bind(this);
}
toggleMood() {
const newMood = this.state.mood == 'good' ? 'bad' : 'good';
this.setState({ mood: newMood });
}
render() {
return (
<div>
<h1>I'm feeling {this.state.mood}!</h1>
<button onClick={this.toggleMood}>Click Me</button>
</div>
);
}
}
const root = ReactDOM.createRoot(document.getElementById('app'));
root.render(<Mood />);
當你透過
this
來定義事件處理器(event handler)時,記得要在建構式中加上this.methodName = this.methodName.bind(this)
。若想瞭解背後的理由,可參考 Handling Events @ React。