初學React的一些觀念整理
關於React:
- React為JavaScript的一個函式庫(library),並非完全是個框架(framework)
- 集中在打造使用者介面(User Interfaces)
- React 提供聲明式 (declarative) 的 API,讓開發者在使用 React 時,只需要描述畫面該怎麼呈現,React會幫忙將這些聲明式的敘述轉譯成實際的畫面渲染至瀏覽器上
React’s tree reconciliation(權衡):
- 當DOM tree要重新被更新的時候,React並不會讓之前已經被渲染的元件重新渲染,而是會使用其Diffing演算法,去比較兩個虛擬DOM(virtual DOM)在記憶體中的差異,並且只更新有變化的子樹結構(sub-tree),這也是React在操作DOM tree特別有效的地方
ReactDOM.render(`React 的元件`, `DOM 節點`):
- 作為React進入DOM的進入點,第一個參數為哪個React元件(React component)要被渲染,第二個參數為哪裡要被渲染,會是靜態的HTML中的結構
React.createElement(`HTML的標籤`, `HTML標籤上的屬性`, `DOM元件的內容`):
- 產生虛擬的元件來代表真實DOM元件,在React中會用物件去表示
- 第一個參數為一般HTML會用到的標記語言,第二個參數例如(id, href, title)等,第三個為選擇性的,可以為內容、子結構、或為空
更新DOM節點(HTML版 vs React版):
const render = () => {
document.getElementById('mountNode').innerHTML = `
<div>
Hello HTML
<input />
<pre>${new Date().toLocaleTimeString()}</pre>
</div>
`;
ReactDOM.render(
React.createElement(
'div',
null,
'Hello React',
React.createElement('input', null),
React.createElement('pre', null, new Date().toLocaleTimeString())
),
document.getElementById('mountNode2')
);
};
setInterval(render, 1000);
由上圖便可得知React版本僅會更新有變動的地方,但是HTML版本會整個都更新
談論React全部都是關於組件(Component):
- 使用組件來描述UI,組件具備重複利用、可組合、具有狀態化
- 可將組件視為一個函式,輸入為props,輸出為整個UI
function Button (props) {
// Returns a DOM/React element here. For example:
return <button type="submit">{props.label}</button>;
}
// To render a Button element in the browser
ReactDOM.render(<Button label="Save" />, mountNode);
React特有的語法JSX:
- JSX像是JavaScript的一個擴充語法,其語法類似於HTML結構,且無法被瀏覽器所識別,需要透過像Babel等工具來進行編譯過才能執行
- 語句中只能有一個根元素
ReactDOM.render(
<div>
<Component1 />
<Component2 />
</div>,
document.getElementById('root')
)
- 當使用一般的字串值當屬性值時,字串使用雙引號(“”)括住,而且等號(=)與屬性之間,以及等號(=)與值之間,不需要加空格
<TodoItem text="buy book" index="1" />
- 當使用花括號({})作為屬性值時,不需要加上雙引號(“”),而且等號(=)與屬性之間,以及等號(=)與值之間,不需要加空格
<TodoItem text={'play game'} index="1" />
- 夾在元件標記或HTML的DOM元素標記的JavaScript程式碼時,一樣也要使用花括號({})框住
<ul>
{this.state.items.map((value, index) => {
return <TodoItem key={index} text={value} index={index} onItemClick={this.handleRemoveItem} />
})}
</ul>
- JSX中的props: 作為父組件傳遞資料給子組件,可以在props裡指定JavaScript的各種原始資料類型和物件、函式、陣列等物件類型的值
- JSX中的子元素: 當子元素是個JSX表達式時,可以用
props.children
作為函式識別名來使用
const TodoItem = (props) => <div>{props.children('world')}</div>ReactDOM.render(
<TodoItem>
{(name)=><div>Hello! {name}</div>}
</TodoItem>,
document.getElementById('root')
)
- JSX中的邏輯與(&&)語法: 當true && expression時,得到expression求出的值;當false && expression時,得到false。當得到false值時,JSX就不輸出任何東西。只有當得到true值時,JSX會以expression(表達式)得到的值來作輸出使用
function Mailbox(props) {
const unreadMessages = props.unreadMessages;
return (
<div>
<h1>Hello!</h1>
{unreadMessages.length > 0 && <h2>You have {unreadMessages.length} unread messages.</h2>}
</div>
);
}
React的生命週期:
- constructor 的作用: 裡面傳props作為初始化用
constructor(props) {
super(props)
}
- shouldComponentUpdate: 呼叫的時間點為改變state後,再去呼叫render
shouldComponentUpdate(nextProps, nextState) {
return false; // 代表不去呼叫render
}
- componentDidMount: componentDidMount被觸發了之後,component才真正被render到DOM上(最適合做初始化相關的東西)
- componentWillUnmount: componentWillUnmount被觸發,代表component正要被render到DOM之前(適合清除一些不會被用到的值)
- componentDidUpdate: 在state更新之後,componentDidUpdate會被觸發
componentDidUpdate(prevProps, prevState) {}