iT邦幫忙

0

筆記|React - 6 - Props

Kim 2023-04-06 21:21:04392 瀏覽
  • 分享至 

  • xImage
  •  

☁️ 開場

這篇筆記主要整理自:官方文件 Passing Props to a Component


🤝 什麼是 Props?

Props 就是你傳給 JSX tag 的資料!

  1. 那些類 HTML 的 tag,可以傳入什麼樣的 props 是已預先設定好,符合 HTML 標準的
舉例:<img/> 裡的 className, src, alt, width, height...
function Avatar() {
  return (
    <img
      className="avatar"
      src="https://i.imgur.com/1bX5QH6.jpg"
      alt="Lin Lanying"
      width={100}
      height={100}
    />
  );
}
  1. Component tag 則可以客製化 props
舉例:Profile 元件傳了 person, size 這兩個 props 給 Avatar 元件
function Profile() {
  return (
    <Avatar
      person={{ name: 'Lin Lanying', imageId: '1bX5QH6' }}
      size={100}
    />
  );
}

Props 能傳遞什麼樣的資料?

看了上面兩個 code block 應該可以猜到,props 可以傳的資料是任何資料型別
文件說:「Props might remind you of HTML attributes, but you can pass any JavaScript value through them, including objects, arrays, and functions.」


🤏 如何取用 Props?

我們撰寫的元件唯一接受的參數就是 props!
承接上一個 code block,Avatar 元件要取用 Profile 元件傳的資料就可以這樣寫:

function Avatar(props) {
  let person = props.person; // person 變數就會收到物件資料
  let size = props.size; // size 變數就會收到數字資料
  // ...
}

🌟 但比起上方的寫法,實務上更常直接在接收 props 的參數時進行物件解構賦值,code 會簡潔很多!

function Avatar({ person, size }) {
  // ...
}

🌟 進階應用:為 props 設定預設值

情境:Avatar 元件沒有收到 size 資料,或是 size 被設定為 undefined,就會使用預設值 100
function Avatar({ person, size = 100 }) {
  // ...
}

🌟 延伸思考:元件接收到很多 props,但其實自己沒有要用,只是單純要往下傳給子元件怎麼寫?

情境:Profile 元件從父元件那邊收到了很多的 props 資料,但自己沒有要用,只是要傳給 Avatar 元件使用

Before:直覺思考可能會這樣寫,缺點是重複性高,優點是看得清楚傳了什麼

function Profile({ person, size, isSepia, thickBorder }) {
  return (
    <div className="card">
      <Avatar
        person={person}
        size={size}
        isSepia={isSepia}
        thickBorder={thickBorder}
      />
    </div>
  );
}

After:這樣寫會簡潔許多,但可能會忘記傳什麼

function Profile(props) {
  return (
    <div className="card">
      <Avatar {...props} />
    </div>
  );
}

⚠️ 文件有提到,如果發現開發時太常使用到上方 <Avatar {...props} /> 這樣的寫法,可能代表還能再思考重構、拆分元件,不然整體易讀性會降低許多,進而影響到維護性


👶 關於 children prop

撰寫元件時很常會寫出巢狀的 tag,像是:

<div>
  <img />
</div>
<Card>
  <Avatar />
</Card>

當 JSX tag 有包裹 content,包住 content 的那個父元件就會接收到叫「children」的 props,值就為該 content

舉例:以下 <h1>App</h1> 就為 Test 元件 props.children 的值
function Test({children}) {
  return <div>{children}</div>;
}

function App() {
  return (
    <Test>
      <h1>App</h1>
    </Test>
  );
}
補充:筆者試著印出以下 code 接收到的 props
function Test(props) {
  console.log(props); // 在這裡印出
  return <div>{props.children}</div>;
}

function App() {
  return (
    <Test size={100}> // 補一個隨意的 props
      <h1>App</h1>
      <h2>App2</h2> // 新增一個元素
    </Test>
  );
}
⬇️ console 畫面

  • 橘色框:可以確認 props 為物件型別
  • 綠色框:在包裹兩個以上的元素,children 會是陣列型別
  • 紫色框:每個被包裹的元素會是以物件型別來呈現,其中的白色箭頭是個人目前覺得可以特別留意的 key
  • 沒有在此圖上:如果 Test 元件只包一個元素,綠色框 children key 的值會直接為物件型別,資料同紫色框所呈現

💃🏻 總結

以下為官方文件的 Recap,不做翻譯,只畫重點

  • To pass props, add them to the JSX, just like you would with HTML attributes.
  • To read props, use the function Avatar({ person, size }) destructuring syntax.
  • You can specify a default value like size = 100, which is used for missing and undefined props.
  • You can forward all props with <Avatar {...props} /> JSX spread syntax, but don’t overuse it!
  • Nested JSX like <Card><Avatar /></Card> will appear as Card component’s  children prop.
  • Props are read-only snapshots in time: every render receives a new version of props.
  • You can’t change props. When you need interactivity, you’ll need to set state.

以上,有任何想法或文內有誤、不清楚歡迎提出,謝謝大家 🙏🏻
.
筆者小記:認識 props 時,腦中就會浮現家長把資料傳給孩子的畫面,然後孩子可以使用這些資料做些事情~


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言