(2024/04/06更新) 因應React在18後更新了許多不同的語法,更新後的教學之後將陸續放在 新的blog 中,歡迎讀者到該處閱讀,我依然會回覆這邊的提問
這個系列和我在12屆鐵人賽的React.js系列文,已經在修訂後和深智數位合作出版成實體書,在天瓏開始預購了,想學React的朋友可以參考看看:
https://www.tenlong.com.tw/products/9789860776188?list_name=srh
第一個要講的「專屬於React的語法」是React component。
在製作網頁時,會有一些功能/元件是很常重複用到 (ex:選單) ,卻又不完全一樣。
如果能讓這些東西被模組化、變成一個自己訂作的元素,而且透過少數的參數控制它們達到我們要的效果,該有多好啊?
這樣的概念下,React component就出現了。
接下來,我們就來製作一個Component。
請打開src資料夾底下的index.js。
並修改為:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import * as serviceWorker from './serviceWorker';
/* 加入下面這一段 */
function App(){
return(
<button>大家好</button>
);
}
/* 加入上面這一段 */
/* 修改div中的東西,改為<App/> */
ReactDOM.render(
<div>
<App/>
</div>,
document.getElementById('root')
);
在這裡App()
函式就成為了我們的component。雖然畫面上出現的是跟【React.js入門 - 05】 JSX (上)中第一項一樣的按鍵,函式除了名稱也都一樣,但我們程式碼中的{函式名稱}
變成了<函式名稱/>
。
咦? 發生了什麼事?
上面這是JSX當中的React component語法,這個語法讓我們可以把程式碼以函式(或是class,後面會提到)包成模組,變成一個自己訂作的元素,然後用跟使用button、div這些元素一樣的語法在JSX中使用,也就是:
<自己的元素名稱/>
/* 或是 */
<自己的元素名稱></自己的元素名稱>
(更新:補個使用React component的規定)
元素名稱第一個字母必須要是大寫、和函式(或class)名稱相同,JSX才會知道這是自製的component
在這種方式下,我們就可以自己做元素,然後給別人or在其他地方重複使用。像下面的程式碼,就是自己做一個進度條:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import * as serviceWorker from './serviceWorker';
function Progress(){
const barWidth="50%";
return(
<div>
<div className="progress-back" style={{backgroundColor:"rgba(0,0,0,0.2)",width:"200px",height:"7px",borderRadius:"10px"}}>
<div className="progress-bar" style={{backgroundColor:"#fe5196",width:barWidth,height:"100%",borderRadius:"10px"}}></div>
</div>
</div>
);
}
/* 加入上面這一段 */
ReactDOM.render(
<div>
<Progress/>
</div>,
document.getElementById('root')
);
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
執行結果:
之後如果要用這個進度條,就不用再重複寫一次,用<Progress/>
就好。
當我們把程式碼模組化後,重複出現的元件就可以不用再寫一遍,這樣的概念就像boostrap把style模組化後可以引入後使用一樣,只是現在我們是自己做自己的元素,功能不只限至於style屬性。
重複利用的方式跟使用html元素一樣。現在我們使用剛剛「大家好」按鍵的程式碼。我們如果把index.js的ReactDOM.render
函式修改為:
ReactDOM.render(
<div>
<App/>
<App/>
<App/>
</div>,
document.getElementById('root')
);
執行結果就會出現:
分檔有助於程式碼的可讀性,專案的架構也會更明確。
也就是我們想把程式階層(hierarchy)從原本的:
index.html
|____ index.js
變成
index.html
|____ index.js
|____ 元件.js
實際上的做法如下:
以module的方式分檔,藉由export default App;
把App函式輸出給引入的對象。注意因為它是React component,還是要以import React from 'react';
引入React。
請打開src資料夾底下的App.js,並修改為:
import React from 'react';
function App(){
return(
<button>大家好</button>
);
}
export default App; //輸出App函式
接著,在原檔加入import App from './App';
引入剛剛寫好的App函式。這樣就完成了分檔的動作。
將src資料夾底下的index.js修改為:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App'; //引入App
import * as serviceWorker from './serviceWorker';
ReactDOM.render(
<div>
<App/>
</div>,
document.getElementById('root')
);
到目前為止,的確在感受上沒有什麼不一樣。但實際上,React還幫component設計了很多功能,這些功能讓component設計/使用起來更方便、或是解決了純使用函式可能產生的問題。在本篇,我們只簡單實作了如何將程式模組化,我們在接下來的章節會從props開始逐步探討。
React component的概念對現代框架造成了巨大的影響,Vue.js、Angular.js也相繼引入了類似的概念。個人認為如果能夠掌握component使用的邏輯,日後即使要切換到其他框架,也能很快速的上手。