James Tsang

James Tsang

A developer.
github
twitter
tg_channel

ARTS 打卡第 10 天 - React 中的 asChild 模式、LLM fine-tune 框架以及關於聆聽的耐心

這兩天忙得耽誤了按天的打卡,還差的先欠著,週末一併補上。

A:58. 最後一個單詞的長度#

給你一個字符串 s,由若干單詞組成,單詞前後用一些空格字符隔開。返回字符串中 最後一個 單詞的長度。
單詞 是指僅由字母組成、不包含任何空格字符的最大子字符串。
示例 1:
輸入:s = "Hello World"
輸出:5
解釋:最後一個單詞是 “World”,長度為 5。
示例 2:
輸入:s = "fly me to the moon"
輸出:4
解釋:最後一個單詞是 “moon”,長度為 4。

function lengthOfLastWord(s: string): number {
  const result = s.trim().split(/\s+/)
  return result[result.length - 1].length
}

提交結果為:

58/58 cases passed (68 ms)
Your runtime beats 42.36 % of typescript submissions
Your memory usage beats 93.1 % of typescript submissions (42.2 MB)

抽到了一道非常簡單的題,因為正則默認是貪婪模式,split 的時候會按最多的空格進行分割,所以很容易就搞定了。

R:Implement Radix's asChild pattern in React#

Q:什麼是 asChild 模式?
一個 UI 庫的組件很難滿足使用者對 options 和組件的全部需求,因此有一種 as 模式被發明出來,傳遞一個組件進去作為默認組件,並在上層組件支持 as 組件的屬性傳遞。

<Button as={Link} />

Radix UI 對這種模式進行了一些改進,變為一個 asChild 屬性,為 true 時則渲染子組件,否則渲染組件的默認形態。

<Button asChild>
  <a href="https://www.jacobparis.com/" />
</Button>

只支持渲染一個子組件,實現大概是這樣:

function Button({ asChild, ...props }: any) {
  const Comp = asChild ? Slot : "button"
  return <Comp {...props} />
}
function Slot({
  children,
}: {
  children?: React.ReactNode
}) {
  if (React.Children.count(children) > 1) {
    throw new Error("Only one child allowed")
  }
  if (React.isValidElement(children)) {
    return React.cloneElement(children)
  }
  return null
}

Q:Slot 在這裡有什麼用?
Slot 組件用於渲染傳遞進來的子組件,做 Props 合併、className 還有 style 的深度合併,以及確保只傳入了一個子組件。

Q:有哪些實現細節?

  • 類型處理:asChildfalse 時需要接受組件的默認屬性;asChildtrue 時建議用戶把屬性都傳遞給子組件。
type AsChildProps<DefaultElementProps> =
  | ({ asChild?: false } & DefaultElementProps)
  | { asChild: true; children: React.ReactNode }
type ButtonProps = AsChildProps<
  React.ButtonHTMLAttributes<HTMLButtonElement>
>
function Button({ asChild, ...props }: ButtonProps) {
  const Comp = asChild ? Slot : "button"
  return <Comp {...props} />
}
  • style 深度合併時子組件的 style 優先級高於父組件優先級,所以要後展開
  • className 深度合併時如果是用的 tailwindcss,可以使用 tailwind-merge 庫來合併,否則直接做字符串拼接即可
  • 使用 React.Children.only(null) 方法來拋出僅支持一個子元素的錯誤

感覺這個模式第一眼看覺得很酷炫,但看完後不知道這是在做什麼,asChild 模式時彷彿就是把原來可以直接渲染子元素的事情抽了一部分 props 放到空殼父元素上去傳遞。另外這樣子組件的 props 類型定義也不好寫,假設一部分屬性是必填的,但是通過父組件來傳遞的,這時子組件相關的 props 不得不寫成 optional 的類型。我看不懂但大受震撼,總體感受好像還不如 renderProps 的實踐。

T:LLaMa-Efficient-Tuning - LLaMA-2 等一系列模型的 Fine-Tune 框架#

目前使用大語言模型完成自己的任務,除了使用 OpenAI、Anthropic 的 API 服務,另一條主要路徑就是使用 LLaMA-2 之類的開源模型 fine-tune 到滿足自己任務的需求的程度然後自己部署使用,這個項目是一個簡單易用的 fine-tune 這些模型的工程框架,可以實現 LLaMA-2, BLOOM, Falcon, Baichuan, Qwen, ChatGLM2 這些主流開源 LLM 的 fine-tune。

S:關於聆聽的耐心#

最近有一個反思,覺得自己以往沒有太多細心聆聽的耐心,總覺得自己已經聽懂了別人想說什麼不想再聽更多我理解了的闡述,於是內心非常著急想表達自己的觀點,導致回應的時候說話語速很快給對方的溝通感受可能也不好,自己的思維也不夠冷靜。於是靜下來想了想,發現自己似乎只在擅長的事情上才有這麼強的表達慾,平時反而又像個悶罐,這並不好,所以還是要有更多聆聽的耐心。以下是具體的反思:

  • 平時不表達因為很多領域沒有表達的能力,一旦遇到了有表達能力的地方,就沒有聆聽的耐心,表達慾過強,不是好事
  • 要從通過說證明價值變成通過聽驗證價值
  • 擅長聆聽既能給對方更好的溝通感受,還能提升自己的 “風度”,又能讓自己有更多更冷靜細緻的思考
  • 想起來 Tinyfool 老師分享的和別人討論問題時,前半個小時都不怎麼表達自己的觀點,只是聽對方說,等對方說完說透了,他再說自己的觀點,也不表現出針對性的反駁,只是說自己認為正確的是怎樣的

參考資料:

  1. ARTS 打卡活動
載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。