---
# System prepended metadata

title: 共筆 - 2025/7/19 Tech Book Community 線下小聚 in 台北 - 【Zet】 React Render Props
tags: [線下小聚]

---

# 2025/7/19 Tech Book Community 線下小聚 in 台北 - 【Zet】 React Render Props

:::info
- Slido
  > https://app.sli.do/event/gpJYqWyjvMpfQfusNpWWMP/live/questions
:::

:::info
- Notion
  > https://zet-chou.notion.site/TBC-React-render-props-design-pattern-1d1a3f5665b080ddbcacf9e320854211
:::

---

[TOC]

---

## Facade Pattern

- 法文來的
- 解決什麼問題
    - 不想在使用的時候，全部的子系統都呼叫一次

## 控制反轉
- 縮寫 IOC
- 兩個點
    - 主程式
    - call 的 API
- 主程式寫的是希望達成什麼效果
    - 把邏輯細節交出去

### React 的 reconciler 如何利用控制反轉
- 不是同步的
- JavaScript 基本上是單執行緒
- React 讓 render 的時候可以被中斷

## 依賴注入
- 可以很方便去替換邏輯
- 不用寫死
- 好測試

## 範例說明
```jsx
// Button 元件：依賴參數（props）來執行某個邏輯與顯示內容
function Button({ text, onClick }) {
  // 宣告：這是一個按鈕元件，透過 React 綁定 onClick 事件，
  // 並將控制權交給瀏覽器在使用者點擊時觸發對應邏輯（IoC）
  // 同時顯示注入的按鈕文字 text
  return <button onClick={onClick}>{text}</button>;
}

function App() {
  // 定義按鈕點擊後要執行的邏輯
  // alert() 是瀏覽器提供的 API，你只需宣告 intent，不主動控制何時執行，屬於 IoC（控制反轉）
  const handleClick = () => alert('hello');

  // 把「文字內容」與「行為邏輯」作為依賴注入給 Button 元件（DI）
  // Button 元件本身不用知道按下去做什麼，只需要拿到依賴就能正常運作
  return <Button text="I am a button" onClick={handleClick} />;
}
```

---

## Render props
- 在純邏輯共用的部分已經被 custom hooks 取代

### Component UI 的抽象化設計用途
- 希望外層元件可以拿到子元件的狀態
- 把該寫死的地方寫死，保持彈性的部分開洞出去

### 練習解答：客製化 counter 結果的渲染邏輯
```jsx
import { useState } from "react";

function Counter({ renderCount }) {
  const [count, setCount] = useState(0);
  const increment = () => setCount((c) => c + 1);
  const decrement = () => setCount((c) => c - 1);
  return (
    <div>
      <button onClick={decrement}>-</button>
      {renderCount(count)}
      <button onClick={increment}>+</button>
    </div>
  );
}

export default function App() {
  return (
    <Counter
      renderCount={(count) =>
        count % 2 === 1 ? <span stylr={{ color: "red" }}>{count}</span> : count
      }
    />
  );
}
```

### 練習解答：延伸上面 ProductList 的範例
- render props 如果只傳單一值，會沒辦法判斷，所以通常就傳整個 item


```jsx
function ProductList({
  items,
  title,
  renderPrice = ({ price }) => "$" + price,
  renderName = ({ name }) => name,
}) {
  return (
    <div>
      <h3>{title}</h3>
      {items.map((item) => (
        <>
          <div>{renderName(item)}</div>
          <div>{renderPrice(item)}</div>
          <hr />
        </>
      ))}
    </div>
  );
}

function DiscountProductList(props) {
  return (
    <ProductList
      {...props}
      renderName={({ name, discountRatio }) =>
        discountRatio <= 0.5 ? (
          <span style={{ color: "red" }}>{name}</span>
        ) : (
          name
        )
      }
      renderPrice={({ price, discountRatio }) => (
        <div>
          <span style={{ textDecoration: "line-through" }}>${price}</span>
          <span>${price * discountRatio}</span>
        </div>
      )}
    />
  );
}

export default function App() {
  return (
    <>
      <ProductList
        title="水果列表"
        items={[
          { name: "蘋果", price: 100 },
          { name: "西瓜", price: 200 },
        ]}
      />
      <DiscountProductList
        title="特價水果列表"
        items={[
          { name: "橘子", price: 300, discountRatio: 0.2 },
          { name: "香蕉", price: 400, discountRatio: 0.9 },
        ]}
      />
    </>
  );
}
```

---

## QA
- 1. 在開發大型專案是如何資料夾結構？2. 狀態管理上，會依據什麼經驗在挑選工具？
> 1. 大哉問，沒有標準答案
> - 以 feature 去分
> - 關鍵字：`component unit`
> 2. 絕大部分專案可能都用不到外部管理系統
> - 以前需要時因為，以前比較難做到狀態管理
> - 跨專案，或是狀態很複雜、比較細的效能需求

- 1. 會建議剛入職1~3年的前端培養什麼能力？有職涯建議嗎？2. 在新創公司要怎麼培養找事情做的能力？3. 在 AI 發達的現在，垂直加深對一個技術的理解 vs. 廣泛多元學習不同框架語言，哪一個效益比較大？
> 1. 把技術的基本功打好
> 不是 CS, OS, 演算法等等
> 對 JS 的理解，Event loop、閉包、當 setState 到看到瀏覽器畫面發生什麼事情
> AI 還很難寫出 Best Practice 的程式碼，所以需要有能力去監督他
> 實際做專案的時候，有沒有追求更好，把東西變成自己的能力
> 遇到需求的時候，有沒有不同的解法，如何取捨利弊
> 時程很趕不是阻擋自己思考的理由
> 2. 嘗試去練習判斷什麼東西更有價值做，從裡面去學習
> 3. 前者

- 在拆元件時，常在想會不會不小心拆太細？想聽講者分享到底該拆多細？
> 意義的邊界
> ProductList 就有商品的概念，List 就不該有

- 在 React 專案規模變大時，會怎麼規劃？是如何處理大型 React 專案中的可維護性與可測試性？
> 在日常當中去思考意義

- 剛開始學習新技能時，會建議怎麼拿捏「先實作」與「了解背後原理」的平衡？要怎麼學習才不會一開始就鑽牛角尖？
> ~~書裡面有寫~~
> 小步前進，先寫寫看，再去看原理，再回頭實作、再看原理，不斷重複下去

---

:::info
* 晚餐出席確認：https://forms.gle/kU6wHioYrGNr6EUn6
* 會後回饋問卷：https://forms.gle/pKPgnMscL6bibTDCA
* 歡迎幫忙上傳照片：https://drive.google.com/drive/folders/1XFTpyJ5vED0LITRkOTSXEpCJUT026rMd?usp=sharing
* 下次 Tech Book Community 小聚調查 - 一起探索 VueUse 背後的黑魔法 🪄：
https://forms.gle/oMBd8TnzrCHCdK5F9

:::

:::info
## 送書活動：
~~- 現場記得最多人資訊的人可直接獲獎一本 [JavaScript 重修就好](https://www.tenlong.com.tw/products/9786267757048)~~
- 會後在 7/26（六）之前寫部落格心得，將網址貼到共筆文件內，在 7/27（日）從中抽一人獲獎一本 [JavaScript 重修就好](https://www.tenlong.com.tw/products/9786267757048)
- 會後在 7/23（三）之前寫回饋（名稱需能夠對應到 KKTIX 訂單），在 7/27（日）從中抽一人獲獎一本 [JavaScript 重修就好](https://www.tenlong.com.tw/products/9786267757048)
:::


:::success
🔔 額外小工商服務
若您也關注台灣的 JavaScript 社群，JSDC 2025 目前正在招募志工。（順帶一提，今年有邀請到尤雨溪喔！歡迎關注 JSDC FB 粉絲專頁）
這與本次 Tech Book Community 小聚無關，但若您有興趣投入 JSDC 的籌備，
歡迎填寫志工報名表單：https://forms.gle/A56No2H5R4PPMW1XA
或是投稿站上 JSDC 舞台：https://forms.gle/ouWSCq82Cf76Lemb8
:::


## 部落格心得連結處

| 稱呼   | 網址                                                       |                    備註                     |
| ------ | ---------------------------------------------------------- |:-------------------------------------------:|
| Celine | https://www.threads.com/@celine.web.learn/post/DMSX7FLS5GW | 我沒有部落格就分享在 threads 上，希望能算XD |
| Kelly  | https://medium.com/@yykTheHusky/d26a2ab3375e               |               好想要那本書RRR               |
| Rafael | https://medium.com/@yhosutun2491/adfdd095264c              |                 真的很有趣                  |
| Monica | https://medium.com/@linyawun031/30a2ddabad42               |     感謝排版小精靈 ＆ Lois & Zet 大大！     |
| Aya    | https://hackmd.io/@NoName21/rkyWI0n8lg                     |                  感謝大家                   |
| Yo0    | https://hackmd.io/@Yo0/By_iVhd8le                          |      感謝各位大大，一場充實的知識旅程~      |
| Tony   |https://medium.com/@yahooleo36/react-思維進化的線下讀書會心得-66dcbd876712 | 感謝 Zet 分享自己的經驗 |
|截止線|截止線|截止線|


## 聊天區

天啊，感謝排版小精靈 😍

`>///<` 

耶～～感謝幫忙筆記 Q&A 的小精靈 🥰

### CodeSandBox 環境暫時解法

- 網址列選擇「網站設定」
![image](https://hackmd.io/_uploads/H1WxyktLgg.png =300x)

- 「不安全的內容」暫時改成「允許」
![image](https://hackmd.io/_uploads/HyMQy1YUlg.png =600x)
