【React 學習】props 初探

2023/12/23閱讀時間約 8 分鐘
這是我最後的 props,收下── (閉嘴啦)

這是我最後的 props,收下── (閉嘴啦)


剛開始接觸 props 時難免有點霧裡看花的感覺,但其實 props 的概念和 JavaScript 函式的參數非常類似。用這篇文章來記錄一下 props 的基本使用方式和注意事項。


什麼是 props?如何傳遞資料?

props 其實為 properties 的縮寫,而在 JavaScript 的世界中,看到 property,我們直覺會聯想到物件屬性,而 props 的確和物件有關係。

props 是 React 提供的特殊物件,讓我們將父元件的資料傳遞給子元件

沒錯,日後只要看到 props,就想像它承載了喬斯達家族的精神,不斷傳遞給下一代的 JOJO 就對了。這樣的運作方式我們其實不陌生,先來回想一下 JavaScript 函式參數吧

function sum() {
return a + b;
}

sum(); // Reference Error: a is not defined


sum() 函式取用了 a、b 兩個值,但不知道它們是何許人也,所以跳出 Reference Error。解決的方法很簡單,將 a、b 當作參數帶入函式即可。

function sum(a, b) {
return a + b;
}

sum(2, 2); // 4


正在學習 React 的我們都知道,元件 (component) 其實就是 JavaScript 函式,所以我們理當能用參數的方式來傳遞資料。但再進一步回想,元件一定要回傳 (return) 一組 JSX 讓 React 進行渲染,而 JSX 和 HTML 標記又非常類似,因此我們不妨將想要傳遞下去的黃金精神資料,以 attribute 的方式寫進 JSX 裡面。

看到了嗎?namecolor 就是 props

function App() {
return <Spirit name="黃金精神" color="golden" />;
}

function Spirit() {
return <div>目前還沒有取用傳遞下來的資料喔</div>;
}


props 能傳遞的資料類型不限字串,數值、陣列、物件、函式都可以。實務上還滿常傳遞物件的,請參考以下程式碼:

const spiritObj = {
name: "黃金精神",
​color: "golden",
value : [
"integrity",
"pride",
"brave",
"dedication"
]
};

function App() {
return <Spirit spiritObj={spiritObj} />;
}

function Spirit() {
return <div>目前還沒有取用傳遞下來的資料喔</div>;
}


透過 propsApp 就可以將資料傳遞給子元件 Spirit 囉。學會傳遞資料之後,接下來還得取用傳下來的資料。


取用 props 資料

前面提過 props 本身是 React 提供的物件,因此我們傳遞的資料,其實都包含在 props 物件裡面了。想一探究竟的話,可以把 props 先列印在 console 喬喬瞧瞧。

export default function App() {
return <Spirit spiritObj={spiritObj} />;
}

function Spirit(props) { // Add props as parameter
console.log(props); // Print props object
return <div>目前還沒有取用傳遞下來的資料喔</div>;
}
raw-image


太好了,那我們使用 dot notation 不就可以取用資料了嗎?的確是這樣沒錯:

const spiritObj = {
name: "黃金精神",
color: "golden",
value: ["integrity", "pride", "brave", "dedication"],
};

export default function App() {
return <Spirit spiritObj={spiritObj} />;
}

function Spirit(props) {
return (
<div style={{ backgroundColor: props.spiritObj.color }}>
{props.spiritObj.name}
</div>
);
}


但由於現在包了兩層物件,所以資料取用的寫法難免冗長,這時候善用解構賦值會是不錯的選項。直接在子元件的 (...) 當中解構,明確指名要使用的 props 資料:

// Before using destructuring​
function Spirit(props) {
return (
<div style={{ backgroundColor: props.spiritObj.color }}>
{props.spiritObj.name}
</div>
);
}

// After using destructuring​
function Spirit({ spiritObj }) {
return (
<div style={{ backgroundColor: spiritObj.color }}>
{spiritObj.name}
</div>
);
}


截至目前來做個小整理:

  • props 是 React 提供的特殊物件,裡面承載父元件要傳遞給子元件的資料,有助於我們去架構、客製化元件,就像 JavaScript 函示的參數。
  • 各種資料類型都可以透過 props 傳遞,舉凡字串、數值、陣列、物件,甚至元件。
  • 由父元件去控制子元件的手段 (我是為你好)。
  • 不想用 props.<key> 的寫法取值,可以善用解構寫法,直接定義 props 當中要使用的資料。



props 注意事項

Immutibility 不可改變

props 是 read-only 的,也就是只能被拿來讀取,無法被更改。聽起來好麻煩喔,為什麼要設下這種規定?因為 React 講求 pure function,其中一項規則,就是函式不能更改 function scope 外面的值。套用到 props 的使用情境,字元件函式不能去改變父元件傳遞下來的資料,要記得資料還是屬於父元件的。

打破 pure function 原則的話,容易形成副作用 (side-effect),造成 debug 的問題,終究也是害到我們這些始作俑者。

如果真要更改 props,請改用 state

One-way data flow 單向資料流

React 採取單向資料流模式,意即資料傳遞僅能由父元件往下傳給子元件,子元件無法逆流將資料往上傳給父元件。這種模式的好處如下:

  • 效能比雙向資料流佳
  • 應用程式的運作更容易預期,因為資料流向是單一的
  • 承接上一點,debug 起來也會比較容易

題外話,Angular 似乎是採用雙向資料流,但沒有那方面的實作經驗,日後遇到會再補充上來。

總而言之,單向資料流讓 props 僅能由上往下傳遞,但 React 似乎有種叫做 controled component 的東西可以達到雙向的效果,這部分也留待日後研究:Understanding data binding in React



參考資料:

16會員
34內容數
Bonjour à tous,我本身是法文系畢業,這邊會刊登純文組學習網頁開發的筆記。如果能鼓勵更多文組夥伴一起學習,那就太開心了~
留言0
查看全部
發表第一個留言支持創作者!