Closed godmmt closed 3 months ago
這篇文章是筆者在學習 React 時,閱讀 React 官方文件 所做的翻譯筆記,希望能幫助更多的人學習 React。(React 官方文件的翻譯筆記將會是一個系列,敬請期待!)
這個章節主要是描述使用者介面,讓你了解如何建立、自定義和有條件地顯示 React 元件等。
這是一個類似於大綱的章節,不會提供過多細節,每個標題底下頂多提供一個簡單的範例,這個章節的目的,是讓初學者對使用者介面有個基本且快速的了解。
本篇文章沒有節錄原文範例的輸出結果,如有需要請至原文對照參考。
每個標題都有延伸的章節可以閱讀,之後筆者會再提供逐篇翻譯。延伸章節有提供實作的部分,建議可以參考原文練習。
React 是一個用於呈現使用者介面(UI)的 JavaScript 函式庫。UI 是由像按鈕、文字和圖像這樣的小單位所建構而成。
React 讓你將它們結合成可重複使用、可嵌套的元件。從網站到手機應用程式,螢幕上的所有內容都可以拆分為元件。
在這一章節中,你將學習建立、自定義和有條件地顯示 React 元件。
React 應用程式由稱為元件的獨立 UI 塊組成。
一個 React 元件是一個你可以在其中加入標籤的 JavaScript 函式。
元件可以小至一個按鈕,大至整個頁面。
以下是一個名為 Gallery
的元件,呈現了三個 Profile
元件:
App.js :
function Profile() {
return <img src='https://i.imgur.com/MK3eW3As.jpg' alt='Katherine Johnson' />;
}
export default function Gallery() {
return (
<section>
<h1>Amazing scientists</h1>
<Profile />
<Profile />
<Profile />
</section>
);
}
閱讀 你的第一個元件 來學習如何宣告和使用 React 元件。
你可以在一個檔案中宣告多個元件,但大型檔案可能會讓導覽變得困難。
為了解決這個問題,你可以將一個元件 匯出(export) 到它自己的檔案中,然後從另一個檔案 匯入(import) 該元件:
Gallery.js :
import Profile from "./Profile.js";
export default function Gallery() {
return (
<section>
<h1>Amazing scientists</h1>
<Profile />
<Profile />
<Profile />
</section>
);
}
Profile.js :
export default function Profile() {
return <img src='https://i.imgur.com/QIrZWGIs.jpg' alt='Alan L. Hart' />;
}
閱讀 匯入與匯出元件 以學習如何將元件分割為它們自己的檔案。
每個 React 元件都是一個 JavaScript 函式,其中可能包含一些標籤(markup),React 會將其呈現到瀏覽器中。
markup: 指的是標記語言中的標記或標籤,用於定義文檔的結構和格式。 在 HTML 中,例如,
<div>
、<p>
和<span>
就是標籤,它們用於將文本和內容組織成可理解的格式。在 React 中,JSX 也是一種類似標籤的語法,用於定義 UI 元素的結構。
React 元件使用一種語法擴展叫做 JSX 來表示該標籤。JSX 看起來很像 HTML,但它更嚴格,並且可以顯示動態資訊。
如果我們將現有的 HTML 標籤(HTML markup)貼到 React 元件中,它不一定會正常運作:
App.js :
export default function TodoList() {
return (
// This doesn't quite work!
<h1>Hedy Lamarr's Todos</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
>
<ul>
<li>Invent new traffic lights
<li>Rehearse a movie scene
<li>Improve spectrum technology
</ul>
);
}
Error
/src/App.js: Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>? (5:4) 3 | // This doesn't quite work! 4 | <h1>Hedy Lamarr's Todos</h1> > 5 | <img | ^ 6 | src="https://i.imgur.com/yXOvdOSs.jpg" 7 | alt="Hedy Lamarr" 8 | class="photo"
如果你有類似這樣的現有 HTML,你可以使用轉換器來修復它:
export default function TodoList() {
return (
<>
<h1>Hedy Lamarr's Todos</h1>
<img src='https://i.imgur.com/yXOvdOSs.jpg' alt='Hedy Lamarr' className='photo' />
<ul>
<li>Invent new traffic lights</li>
<li>Rehearse a movie scene</li>
<li>Improve spectrum technology</li>
</ul>
</>
);
}
閱讀 使用 JSX 撰寫標籤 以學習如何撰寫有效的 JSX。
JSX 允許你在 JavaScript 檔案中寫入類似 HTML 的標籤,將渲染邏輯和內容放在同一個地方。
有時你會希望在該標籤中添加一些 JavaScript 邏輯或引用動態屬性。
在這種情況下,你可以在 JSX 中使用花括號來“打開一個窗口”到 JavaScript:
const person = {
name: "Gregorio Y. Zara",
theme: {
backgroundColor: "black",
color: "pink",
},
};
export default function TodoList() {
return (
<div style={person.theme}>
<h1>{person.name}'s Todos</h1>
<img className='avatar' src='https://i.imgur.com/7vQD0fPs.jpg' alt='Gregorio Y. Zara' />
<ul>
<li>Improve the videophone</li>
<li>Prepare aeronautics lectures</li>
<li>Work on the alcohol-fuelled engine</li>
</ul>
</div>
);
}
閱讀 JSX 中的 JavaScript 與花括號 以學習如何從 JSX 中訪問 JavaScript 資料。
React 元件使用 props 來彼此通訊。
每個父元件都可以通過將 props 傳遞給其子元件來傳遞一些資訊。
Props 可能讓你想到了 HTML 屬性,但你可以通過它們傳遞任何 JavaScript 值,包括物件、陣列、函式,甚至是 JSX!
App.js :
import { getImageUrl } from "./utils.js";
export default function Profile() {
return (
<Card>
<Avatar
size={100}
person={{
name: "Katsuko Saruhashi",
imageId: "YfeOqp2",
}}
/>
</Card>
);
}
function Avatar({ person, size }) {
return <img className='avatar' src={getImageUrl(person)} alt={person.name} width={size} height={size} />;
}
function Card({ children }) {
return <div className='card'>{children}</div>;
}
utils.js :
export function getImageUrl(person, size = "s") {
return "https://i.imgur.com/" + person.imageId + size + ".jpg";
}
閱讀 將 Props 傳遞給元件 以學習如何傳遞和讀取 props。
你的元件通常會根據不同的條件顯示不同的內容。在 React 中,你可以使用 JavaScript 語法,如 if
語句、 &&
和 ? :
運算子(operator)來有條件地渲染 JSX。
在這個例子中,使用了 JavaScript 的 &&
運算子來有條件地渲染一個勾勾符號(checkmark):
function Item({ name, isPacked }) {
return (
<li className='item'>
{name} {isPacked && "✔"}
</li>
);
}
export default function PackingList() {
return (
<section>
<h1>Sally Ride's Packing List</h1>
<ul>
<Item isPacked={true} name='Space suit' />
<Item isPacked={true} name='Helmet with a golden leaf' />
<Item isPacked={false} name='Photo of Tam' />
</ul>
</section>
);
}
閱讀 條件渲染 以學習不同的條件渲染內容的方式。
你通常會想要從一組資料中顯示多個相似的元件。
你可以在 React 中使用 JavaScript 的 filter()
和 map()
來過濾和轉換你的資料陣列為元件陣列。
對於每個陣列項目,你需要指定一個 key
。
通常,你會希望使用來自資料庫的 ID 作為 key
。key
讓 React 能夠跟蹤列表中每個項目的位置,即使列表發生變化。
App.js :
import { people } from "./data.js";
import { getImageUrl } from "./utils.js";
export default function List() {
const listItems = people.map((person) => (
<li key={person.id}>
<img src={getImageUrl(person)} alt={person.name} />
<p>
<b>{person.name}:</b>
{" " + person.profession + " "}
known for {person.accomplishment}
</p>
</li>
));
return (
<article>
<h1>Scientists</h1>
<ul>{listItems}</ul>
</article>
);
}
data.js :
export const people = [
{
id: 0,
name: "Creola Katherine Johnson",
profession: "mathematician",
accomplishment: "spaceflight calculations",
imageId: "MK3eW3A",
},
{
id: 1,
name: "Mario José Molina-Pasquel Henríquez",
profession: "chemist",
accomplishment: "discovery of Arctic ozone hole",
imageId: "mynHUSa",
},
{
id: 2,
name: "Mohammad Abdus Salam",
profession: "physicist",
accomplishment: "electromagnetism theory",
imageId: "bE7W1ji",
},
{
id: 3,
name: "Percy Lavon Julian",
profession: "chemist",
accomplishment: "pioneering cortisone drugs, steroids and birth control pills",
imageId: "IOjWm71",
},
{
id: 4,
name: "Subrahmanyan Chandrasekhar",
profession: "astrophysicist",
accomplishment: "white dwarf star mass calculations",
imageId: "lrWQx8l",
},
];
utils.js :
export function getImageUrl(person) {
return "https://i.imgur.com/" + person.imageId + "s.jpg";
}
閱讀 渲染清單 以學習如何渲染一個元件清單,以及如何選擇一個鍵(key)。
某些 JavaScript 函式是 純函式 。一個純函式具有以下特性:
嚴格地只將你的元件編寫為純函式,你就可以避免在程式碼庫增長時,遇到的一整類令人困惑的錯誤和不可預測的行為。以下是一個不純的元件的例子:
App.js :
let guest = 0;
function Cup() {
// Bad: changing a preexisting variable!
guest = guest + 1;
return <h2>Tea cup for guest #{guest}</h2>;
}
export default function TeaSet() {
return (
<>
<Cup />
<Cup />
<Cup />
</>
);
}
你可以通過傳遞一個 prop,而不是修改一個預先存在的變數,來使這個元件成為純函式(make this component pure):
App.js :
function Cup({ guest }) {
return <h2>Tea cup for guest #{guest}</h2>;
}
export default function TeaSet() {
return (
<>
<Cup guest={1} />
<Cup guest={2} />
<Cup guest={3} />
</>
);
}
閱讀 保持元件的純函式特性 以學習如何將元件編寫為純函式,以獲得可預測性。
React 使用樹狀結構來模擬(model)元件和模組之間的關係。一個 React 渲染樹(React render tree)是對元件之間父子關係的表示。
An example React render tree:
靠近樹的頂部、根元件附近的元件被認為是頂級元件(top-level components)。
沒有子元件的元件被稱為葉子元件(leaf components)。
這種元件的分類對於理解資料流(data flow)和渲染效能(rendering performance)非常有用。
對於理解你的應用程式,模擬(model) JavaScript 模組之間的關係是另一種有用的方式。我們稱之為模組依賴樹(module dependency tree)。
model: 表示建模或模擬的行為。
An example module dependency tree:
依賴樹通常被建構工具(build tools)用來將所有相關的 JavaScript 程式碼打包(bundle),供客戶端下載和渲染(download and render)。
對於 React 應用程式而言,較大的打包尺寸會降低使用者體驗。了解模組依賴樹有助於解決此類問題。
閱讀 將你的 UI 視為樹狀結構 以學習如何為 React 應用程式創建渲染和模組依賴樹,以及它們如何作為改善使用者體驗和性能的有用心智模型。
此章節簡易的介紹了 React 的基本概念,讓你了解如何建立、自定義和有條件地顯示 React 元件等。這篇文章只是初淺的概念而已,如果想要更深入的了解,建議可以閱讀延伸閱讀的章節。(或者等筆者發布新的翻譯筆記?)
剛開始學習一門新的程式語言時,不曉得各位讀者傾向於哪種學習方式呢?
有些人喜歡閱讀官方文件、有些人喜歡看影片教學、有些人喜歡參考網路文章等。不管是哪種方式,只要能夠讓自己理解並且掌握,都是好的學習方式。(當然,最好的學習方式是多方面的學習,也就是「我全都要」。)
筆者喜歡的學習方法是一邊看教學影片、一邊實作,再閱讀官方文件,把相關的概念串起來。雖然嗑英文的時間比較久,但官方文件是最正確的資訊,所以不怕嗑錯?(笑)
描述使用者介面:揭示 React 元件的威力
這篇文章是筆者在學習 React 時,閱讀 React 官方文件 所做的翻譯筆記,希望能幫助更多的人學習 React。(React 官方文件的翻譯筆記將會是一個系列,敬請期待!)
這個章節主要是描述使用者介面,讓你了解如何建立、自定義和有條件地顯示 React 元件等。
這是一個類似於大綱的章節,不會提供過多細節,每個標題底下頂多提供一個簡單的範例,這個章節的目的,是讓初學者對使用者介面有個基本且快速的了解。
本篇文章沒有節錄原文範例的輸出結果,如有需要請至原文對照參考。
每個標題都有延伸的章節可以閱讀,之後筆者會再提供逐篇翻譯。延伸章節有提供實作的部分,建議可以參考原文練習。
React 是一個用於呈現使用者介面(UI)的 JavaScript 函式庫。UI 是由像按鈕、文字和圖像這樣的小單位所建構而成。
React 讓你將它們結合成可重複使用、可嵌套的元件。從網站到手機應用程式,螢幕上的所有內容都可以拆分為元件。
在這一章節中,你將學習建立、自定義和有條件地顯示 React 元件。
React 應用程式由稱為元件的獨立 UI 塊組成。
一個 React 元件是一個你可以在其中加入標籤的 JavaScript 函式。
元件可以小至一個按鈕,大至整個頁面。
以下是一個名為 Gallery
的元件,呈現了三個 Profile
元件:
App.js :
function Profile() {
return <img src='https://i.imgur.com/MK3eW3As.jpg' alt='Katherine Johnson' />;
}
export default function Gallery() {
return (
<section>
<h1>Amazing scientists</h1>
<Profile />
<Profile />
<Profile />
</section>
);
}
閱讀 你的第一個元件 來學習如何宣告和使用 React 元件。
你可以在一個檔案中宣告多個元件,但大型檔案可能會讓導覽變得困難。
為了解決這個問題,你可以將一個元件 匯出(export) 到它自己的檔案中,然後從另一個檔案 匯入(import) 該元件:
Gallery.js :
import Profile from "./Profile.js";
export default function Gallery() {
return (
<section>
<h1>Amazing scientists</h1>
<Profile />
<Profile />
<Profile />
</section>
);
}
Profile.js :
export default function Profile() {
return <img src='https://i.imgur.com/QIrZWGIs.jpg' alt='Alan L. Hart' />;
}
閱讀 匯入與匯出元件 以學習如何將元件分割為它們自己的檔案。
每個 React 元件都是一個 JavaScript 函式,其中可能包含一些標籤(markup),React 會將其呈現到瀏覽器中。
markup:
指的是標記語言中的標記或標籤,用於定義文檔的結構和格式。
在 HTML 中,例如,<div>
、<p>
和<span>
就是標籤,它們用於將文本和內容組織成可理解的格式。
在 React 中,JSX 也是一種類似標籤的語法,用於定義 UI 元素的結構。
React 元件使用一種語法擴展叫做 JSX 來表示該標籤。JSX 看起來很像 HTML,但它更嚴格,並且可以顯示動態資訊。
如果我們將現有的 HTML 標籤(HTML markup)貼到 React 元件中,它不一定會正常運作:
App.js :
export default function TodoList() {
return (
// This doesn't quite work!
<h1>Hedy Lamarr's Todos</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
>
<ul>
<li>Invent new traffic lights
<li>Rehearse a movie scene
<li>Improve spectrum technology
</ul>
);
}
Error :
/src/App.js: Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>? (5:4) 3 | // This doesn't quite work! 4 | <h1>Hedy Lamarr's Todos</h1> > 5 | <img | ^ 6 | src="https://i.imgur.com/yXOvdOSs.jpg" 7 | alt="Hedy Lamarr" 8 | class="photo"
如果你有類似這樣的現有 HTML,你可以使用轉換器來修復它:
export default function TodoList() {
return (
<>
<h1>Hedy Lamarr's Todos</h1>
<img src='https://i.imgur.com/yXOvdOSs.jpg' alt='Hedy Lamarr' className='photo' />
<ul>
<li>Invent new traffic lights</li>
<li>Rehearse a movie scene</li>
<li>Improve spectrum technology</li>
</ul>
</>
);
}
閱讀 使用 JSX 撰寫標籤 以學習如何撰寫有效的 JSX。
JSX 允許你在 JavaScript 檔案中寫入類似 HTML 的標籤,將渲染邏輯和內容放在同一個地方。
有時你會希望在該標籤中添加一些 JavaScript 邏輯或引用動態屬性。
在這種情況下,你可以在 JSX 中使用花括號來“打開一個窗口”到 JavaScript:
const person = {
name: "Gregorio Y. Zara",
theme: {
backgroundColor: "black",
color: "pink",
},
};
export default function TodoList() {
return (
<div style={person.theme}>
<h1>{person.name}'s Todos</h1>
<img className='avatar' src='https://i.imgur.com/7vQD0fPs.jpg' alt='Gregorio Y. Zara' />
<ul>
<li>Improve the videophone</li>
<li>Prepare aeronautics lectures</li>
<li>Work on the alcohol-fuelled engine</li>
</ul>
</div>
);
}
閱讀 JSX 中的 JavaScript 與花括號 以學習如何從 JSX 中訪問 JavaScript 資料。
React 元件使用 props 來彼此通訊。
每個父元件都可以通過將 props 傳遞給其子元件來傳遞一些資訊。
Props 可能讓你想到了 HTML 屬性,但你可以通過它們傳遞任何 JavaScript 值,包括物件、陣列、函式,甚至是 JSX!
App.js :
import { getImageUrl } from "./utils.js";
export default function Profile() {
return (
<Card>
<Avatar
size={100}
person={{
name: "Katsuko Saruhashi",
imageId: "YfeOqp2",
}}
/>
</Card>
);
}
function Avatar({ person, size }) {
return <img className='avatar' src={getImageUrl(person)} alt={person.name} width={size} height={size} />;
}
function Card({ children }) {
return <div className='card'>{children}</div>;
}
utils.js :
export function getImageUrl(person, size = "s") {
return "https://i.imgur.com/" + person.imageId + size + ".jpg";
}
閱讀 將 Props 傳遞給元件 以學習如何傳遞和讀取 props。
你的元件通常會根據不同的條件顯示不同的內容。在 React 中,你可以使用 JavaScript 語法,如 if
語句、 &&
和 ? :
運算子(operator)來有條件地渲染 JSX。
在這個例子中,使用了 JavaScript 的 &&
運算子來有條件地渲染一個勾勾符號(checkmark):
function Item({ name, isPacked }) {
return (
<li className='item'>
{name} {isPacked && "✔"}
</li>
);
}
export default function PackingList() {
return (
<section>
<h1>Sally Ride's Packing List</h1>
<ul>
<Item isPacked={true} name='Space suit' />
<Item isPacked={true} name='Helmet with a golden leaf' />
<Item isPacked={false} name='Photo of Tam' />
</ul>
</section>
);
}
閱讀 條件渲染 以學習不同的條件渲染內容的方式。
你通常會想要從一組資料中顯示多個相似的元件。
你可以在 React 中使用 JavaScript 的 filter()
和 map()
來過濾和轉換你的資料陣列為元件陣列。
對於每個陣列項目,你需要指定一個 key
。
通常,你會希望使用來自資料庫的 ID 作為 key
。key
讓 React 能夠跟蹤列表中每個項目的位置,即使列表發生變化。
App.js :
import { people } from "./data.js";
import { getImageUrl } from "./utils.js";
export default function List() {
const listItems = people.map((person) => (
<li key={person.id}>
<img src={getImageUrl(person)} alt={person.name} />
<p>
<b>{person.name}:</b>
{" " + person.profession + " "}
known for {person.accomplishment}
</p>
</li>
));
return (
<article>
<h1>Scientists</h1>
<ul>{listItems}</ul>
</article>
);
}
data.js :
export const people = [
{
id: 0,
name: "Creola Katherine Johnson",
profession: "mathematician",
accomplishment: "spaceflight calculations",
imageId: "MK3eW3A",
},
{
id: 1,
name: "Mario José Molina-Pasquel Henríquez",
profession: "chemist",
accomplishment: "discovery of Arctic ozone hole",
imageId: "mynHUSa",
},
{
id: 2,
name: "Mohammad Abdus Salam",
profession: "physicist",
accomplishment: "electromagnetism theory",
imageId: "bE7W1ji",
},
{
id: 3,
name: "Percy Lavon Julian",
profession: "chemist",
accomplishment: "pioneering cortisone drugs, steroids and birth control pills",
imageId: "IOjWm71",
},
{
id: 4,
name: "Subrahmanyan Chandrasekhar",
profession: "astrophysicist",
accomplishment: "white dwarf star mass calculations",
imageId: "lrWQx8l",
},
];
utils.js :
export function getImageUrl(person) {
return "https://i.imgur.com/" + person.imageId + "s.jpg";
}
閱讀 渲染清單 以學習如何渲染一個元件清單,以及如何選擇一個鍵(key)。
某些 JavaScript 函式是 純函式 。一個純函式具有以下特性:
嚴格地只將你的元件編寫為純函式,你就可以避免在程式碼庫增長時,遇到的一整類令人困惑的錯誤和不可預測的行為。以下是一個不純的元件的例子:
App.js :
let guest = 0;
function Cup() {
// Bad: changing a preexisting variable!
guest = guest + 1;
return <h2>Tea cup for guest #{guest}</h2>;
}
export default function TeaSet() {
return (
<>
<Cup />
<Cup />
<Cup />
</>
);
}
你可以通過傳遞一個 prop,而不是修改一個預先存在的變數,來使這個元件成為純函式(make this component pure):
App.js :
function Cup({ guest }) {
return <h2>Tea cup for guest #{guest}</h2>;
}
export default function TeaSet() {
return (
<>
<Cup guest={1} />
<Cup guest={2} />
<Cup guest={3} />
</>
);
}
閱讀 保持元件的純函式特性 以學習如何將元件編寫為純函式,以獲得可預測性。
React 使用樹狀結構來模擬(model)元件和模組之間的關係。
model: 表示建模或模擬的行為。
一個 React 渲染樹(React render tree)是對元件之間父子關係的表示。
An example React render tree:
靠近樹的頂部、根元件附近的元件被認為是頂級元件(top-level components)。
沒有子元件的元件被稱為葉子元件(leaf components)。
這種元件的分類對於理解資料流(data flow)和渲染效能(rendering performance)非常有用。
對於理解你的應用程式,模擬 JavaScript 模組之間的關係是另一種有用的方式。我們稱之為模組依賴樹(module dependency tree)。
An example module dependency tree:
依賴樹通常被建構工具(build tools)用來將所有相關的 JavaScript 程式碼打包(bundle),供客戶端下載和渲染(download and render)。
對於 React 應用程式而言,較大的打包尺寸會降低使用者體驗。了解模組依賴樹有助於解決此類問題。
閱讀 將你的 UI 視為樹狀結構 以學習如何為 React 應用程式創建渲染和模組依賴樹,以及它們如何作為改善使用者體驗和性能的有用心智模型。
此章節簡易的介紹了 React 的基本概念,讓你了解如何建立、自定義和有條件地顯示 React 元件等。這篇文章只是初淺的概念而已,如果想要更深入的了解,建議可以閱讀延伸閱讀的章節。(或者等筆者發布新的翻譯筆記?)
剛開始學習一門新的程式語言時,不曉得各位讀者傾向於哪種學習方式呢?
有些人喜歡閱讀官方文件、有些人喜歡看影片教學、有些人喜歡參考網路文章等。不管是哪種方式,只要能夠讓自己理解並且掌握,都是好的學習方式。(當然,最好的學習方式是多方面的學習,也就是「我全都要」。)
筆者喜歡的學習方法是一邊看教學影片、一邊實作,再閱讀官方文件,把相關的概念串起來。雖然嗑英文的時間比較久,但官方文件是最正確的資訊,所以不怕嗑錯?(笑)
took 8 hours
done
Describing the UI: Unveiling the Power of React Components
描述使用者介面:揭示 React 元件的威力
文章位置: https://github.com/CAFECA-IO/WorkGuidelines/blob/main/newbie/react-document/describing-the-ui.md
KM Steps: