iT邦幫忙

2021 iThome 鐵人賽

DAY 21
1
自我挑戰組

Re: 從 Next.js 開始的 React 生活系列 第 21

[Day21] 在 Codecademy 學 React ~ What's this? This is "this"! 之 this.props 篇

  • 分享至 

  • xImage
  •  

前言

今天要來講 this.props 了,
但在那之前我發現我還沒講過 this XD
就跟學英文一樣第一句要學的是 "This is a pen.",
那麼要開始學 props 之前我們當然也要來學 This is "this" 囉XD
那就讓我們開始吧!Codecademy - this.props

本日正文

What's "this"

this 是 React 很常使用的語法,
(雖然我現在比較常用的寫法不會用到 this 就是了XD")
在 Codecademy 一開始用了一個範例,
這邊也讓大家猜一下這邊的 this 指的是誰:

class IceCreamGuy extends React.Component {
  get food() {
    return 'ice cream';
  }
 
  render() {
    return <h1>I like {this.food}.</h1>;
  }
}

答案就是 IceCreamGuy,
Codecademy 上的說明是這樣的:

The simple answer is that this refers to an instance of IceCreamGuy.
The less simple answer is that this refers to the object on which this‘s enclosing method, in this case .render(), is called.

簡單來說 this 是指 IceCreamGuy 的實體,
更簡單的答案是 this 指向將 this 封閉的 method (render),其所屬的物件上(render 屬於 IceCreamGuy)

但老實說 this 我也不太曉得怎麼解釋比較好,
所以這邊就直接引 Codecademy 的說明,
Codecademy 在這邊也有附一篇文章讓大家更了解 this,
https://dmitripavlutin.com/gentle-explanation-of-this-in-javascript/
總之我個人先把 this 當作是當下其所屬的容器(?

另外有找到卡斯伯老師關於 this 的說明文章,大家可以參考XD

this.props

上面對 this 有初步概念後,
就直接來講 this.props 吧!
props 是指 properties,
所以 this.props 顧名思義就是目前這個容器(component)的屬性,
例如一個水果會有名字、顏色、價格等屬性。

那麼我先在 Fruits.js 宣告一個 Fruit 的 class,
裡面分別用 this.props 取得三個屬性:name, color, price,
像這樣:

import React from "react";

export class Fruit extends React.Component {
  render() {
    return (
      <div>
        <h1>這是一個{this.props.name}</h1>
        <h1>顏色:{this.props.color}</h1>
        <h1>價格:{this.props.price}元</h1>
      </div>
    );
  }
}

而我在主頁面 App.js 引入 Fruits.js 的 Fruit class,
並在 <Fruit> 的標籤裡分別設定它 name, color, price 的值,

<Fruit name="蘋果" color="青綠色" price="100" />

像這樣:

import { Fruit } from "./Fruits.js";

export default function App() {
  return (
    <div className="App">
      <Fruit name="蘋果" color="青綠色" price="100" />
    </div>
  );
}

https://ithelp.ithome.com.tw/upload/images/20210923/201298733NkAs6eVts.png

然後就可以看到畫面出現剛剛上面所設定的那些值。
再回過頭看一下 Fruits.js 的這句:{this.props.name}
這邊的 this 是指 Fruit,所以這意思是我要取用 Fruit 中 name 屬性的值。

因此在 App.js 實際放了 <Fruit> 的 component,
<Fruit> 設定 name 屬性,值為"蘋果"。
<Fruit name="蘋果">
這樣 {this.props.name} 就會去找到 <Fruit> name 被設定的值,
並將結果渲染在頁面上,
<h1>這是一個{this.props.name}</h1>
因此這樣就會出現 這是一個蘋果 的內容。

而這邊屬性都可以自訂~

this.props 的 Event Handler

除了上述的自訂屬性之外,Event Handler 也可以被當成一種屬性,
因此我也可以寫 {this.props.onClick} 去取得屬性 onClick 裡面的值。

例如我現在 Button.js 宣告一個 Button 的 class,

import React from "react";

export class Button extends React.Component {
  render() {
    return <button onClick={this.props.onClick}>點我購買!</button>;
  }
}

再來在 Talker.js 宣告一個 Talker 的 class,
裡面宣告一個 handleClick 的 函數,

handleClick() {
    let speech = "";
    for (let i = 0; i < 500; i++) {
      speech += "金額不足";
    }
    alert(speech);
}

以及放入 <Button> 的 component,
並給它 onClick 屬性,值指向 {this.handleClick}

render() {
    return <Button onClick={this.handleClick} />;
}

先讓大家看成果:

說明:
在 Button.js <button onClick={this.props.onClick}>
onClick 會指向 <Talker><Button> onClick 屬性的值,
<Talker><Button> onClick 屬性的值又被指向 {this.handleClick}
所以最後指向的是在 Talker.js 裡面的 handleClick 函數,
因此上面點擊按鈕才會出現警告跳窗。

這邊用圖示應該會比較好懂一點:
https://ithelp.ithome.com.tw/upload/images/20210923/201298733B4b4zPQe4.png

this.props 的 children

每個 component 都會有 children 的屬性,
this.props.children 就是指該 component 裡面包的所有東西。

例如我在原本 App.js <Talker /> 的地方擴寫成這樣:

<Talker>
    <p>之後將會上架更多水果,敬請期待</p>
</Talker>

但你發現沒有任何變化,
所以這時候我們在 Talker.js 將原本 render 的地方擴寫成這樣:

render() {
    return (
      <div>
        <Button onClick={this.handleClick} />
        {this.props.children}
      </div>
    );
}

https://ithelp.ithome.com.tw/upload/images/20210923/201298739csPNtkdfW.png

這邊加上了 {this.props.children} 之後,
就出現我們之前在 <Talker> 裡面增加的 <p>之後將會上架更多水果,敬請期待</p> 了。

說明:
Talker.js 裡面的 {this.props.children} 意思是會去找到 <Talker></Talker> 裡面包的內容,
將其顯示在這裡,
這邊架構圖會是這樣:
https://ithelp.ithome.com.tw/upload/images/20210923/20129873aEJ7uAIRmr.png

defaultProps

這意思是是要給予屬性預設值,當該 component 沒有被設定屬性值的時候就要 default 顯示的值。

比如說把原本按鈕內的文字「點我購買!」改成 {this.props.text}

<button onClick={this.props.onClick}>{this.props.text}</button>

這時候會發現按鈕的文字不見了。
https://ithelp.ithome.com.tw/upload/images/20210923/201298737alp5nW3yO.png

但我在 Button.js 下面多加了這行設定,

Button.defaultProps = { text: "銷售一空" };

這樣會發現即使在 Talker.js 中 <Button> 裡我沒給予 text 這個屬性,
依然會顯示「銷售一空」的字眼。
https://ithelp.ithome.com.tw/upload/images/20210923/20129873uNE0DFIkLS.png

那如果我現在在 Talker.js 中 <Button> 裡給予 text 這個屬性並設定值,
像這樣:

<Button onClick={this.handleClick} text="點我購買!" />

發現按鈕文字又從「銷售一空」變為「點我購買!」了。
https://ithelp.ithome.com.tw/upload/images/20210923/20129873xaa2PQl7Ry.png

這個適合在如果這個屬性一定都會有預設值使用。

今日程式暨檔案架構

然後我終於研究好如何在 CodeSandbox 放我在 Codecademy 的這些練習了,
因此附上今日程式:Day21 Codecademy - this.props

然後說明一下檔案架構:
index.js 引入 App.js,並置入 <App />

ReactDOM.render(
  <StrictMode>
    <App />
  </StrictMode>,
  rootElement
);

因此 App.js 才是真的寫主程式的地方。

App.js 引入 Fruits.js, Talker.js,
Talker.js 再引入 Button.js 。
https://ithelp.ithome.com.tw/upload/images/20210923/20129873XdZXSNbvPX.png
https://ithelp.ithome.com.tw/upload/images/20210923/20129873itKNq4Jv7Y.png

如果對 component 如何宣告及引入使用不熟悉的可以參考我昨天的文章 →
[Day20] 在 Codecademy 學 React ~ 如何宣告 Component 及使用 Component 的好處

後記

其實 this.props 也是滿多東西可以學習的,
但是我之前沒有寫過 this.props
所以現在對我來說這樣的寫法有點囉嗦就是了XD
例如上面範例介紹的 {this.props.name} 之前我的寫法都只會寫 {name} XD

明天來學 this.state XD


上一篇
[Day20] 在 Codecademy 學 React ~ 如何宣告 Component 及使用 Component 的好處
下一篇
[Day22] 在 Codecademy 學 React ~ 原來 useState 就是 this.state + this.setState 啊!
系列文
Re: 從 Next.js 開始的 React 生活31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言