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。

Copy
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 组件的属性传递。

Copy


Radix UI 对这种模式进行了一些改进，变为一个 asChild 属性，为 true 时则渲染子组件，否则渲染组件的默认形态。

Copy




只支持渲染一个子组件，实现大概是这样：

Copy
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：有哪些实现细节？

类型处理：asChild 为 false 时需要接受组件的默认属性；asChild 为 true 时建议用户把属性都传递给子组件。

Copy
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 老师分享的和别人讨论问题时，前半个小时都不怎么表达自己的观点，只是听对方说，等对方说完说透了，他再说自己的观点，也不表现出针对性的反驳，只是说自己认为正确的是怎样的

Reference:

ARTS 打卡活动