初探React — 學習筆記

YuCheng
7 min readSep 13, 2020

初學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的生命週期:

source: https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/
  • 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) {}

--

--