标签函数返回首个参数时为何拿不到模板字面量插值?插值函数何时执行?
问题解答
1. 标签函数的参数结构说明
你之前实现的标签函数只接收了第一个参数,所以只能拿到被插值分割的字符串数组。实际上标签函数的完整传参规则是:
- 第一个参数:字符串数组,由所有插值表达式把模板字符串分割后的静态片段组成
- 从第二个参数开始的剩余参数:对应模板中每个插值表达式的计算结果
你可以修改你的测试代码验证这一点:
(strings, ...interpolations) => [strings, interpolations]`Hello world ${s => s.toUpperCase()}` // 输出结果: // [ // [ 'Hello world ', '' ], // [ [Function (anonymous)] ] // ]
你例子中的s、styled-components示例中的props都属于插值函数的形参,实际参数是由标签函数的内部逻辑在调用这些插值函数时传入的。
2. 插值函数的调用时机
这些插值函数不会在标签模板字面量执行时调用,只会在标签函数内部的业务逻辑需要计算最终值的时候触发调用。
对应styled-components的场景:
- 你调用
styled.button模板语法时,只会先收集静态字符串数组和所有插值函数,返回一个React组件 - 当这个组件被渲染时,styled-components内部会拿到组件当前接收的所有props,遍历所有插值,只要插值是函数类型,就会把props作为参数传入调用这个函数,拿到返回的样式值,最终和静态字符串拼接成完整的CSS样式,应用到元素上。
简化版styled.button实现参考
你可以参考这个极简实现理解整个流程:
const styled = { button: (strings, ...interpolations) => { // 返回React组件 return (props) => { // 组件渲染时计算最终CSS字符串 const finalCss = strings.reduce((css, str, index) => { const interp = interpolations[index]; // 插值为函数时传入props调用获取样式值 const interpVal = typeof interp === 'function' ? interp(props) : interp || ''; return css + str + interpVal; }, ''); // 此处省略CSS字符串转行内样式对象/生成类名插入样式表的逻辑 return <button {...props} /> } } }
内容的提问来源于stack exchange,提问作者Xiphias
相关产品推荐
相关产品推荐

