Styled Components中多箭头函数与合并单箭头函数写法如何选择?
两种写法跑起来效果完全一致,没有功能层面的差异,但不是纯粹的个人编码偏好选择,在性能、维护成本上存在可量化的区别,具体可以拆成几个维度说:
首先是两种写法的对照:
// 写法1:每个插值单独写箭头函数取props const Button = styled.button` background-color: ${({ theme }) => theme.colors.blue}; padding: ${({ hasSpacing }) => hasSpacing ? '10px 20px' : null}; `; // 写法2:外层单个箭头函数包裹css模板 const Button = styled.button(({ theme, hasPadding }) => css` background-color: ${theme.colors.blue}; padding: ${hasPadding ? '10px 20px' : null}; `);
性能差异
写法1的运行逻辑是模板里有多少个动态插值,组件每次重渲染就会执行多少次对应的插值函数。上面的例子里有2个插值,每次重渲染就会单独跑2次函数读props。要是碰到有十几条动态样式的复杂组件,攒下来的函数调用开销还是能感知到的。
写法2每次重渲染只会执行1次外层的箭头函数,拿到完整css片段后再统一解析,函数调用开销低很多,动态样式规则越多,这个性能优势越明显。
要注意:如果用写法2的时候,在css模板内部还是每个插值单独写箭头函数读props,那性能和写法1没有任何区别,拿不到这个优势。生成CSS类数量差异
这一块两种写法完全没区别。styled-components判断要不要生成新CSS类的逻辑,是看最终算出来的CSS字符串内容和已有类是否重复,和你用什么形式写插值没有关系。相同props下两种写法生成的最终CSS规则完全一致,不会多出冗余类。打包体积差异
写法2需要额外引入css工具函数,单组件场景下会有几乎可以忽略的微小导入成本,但只要项目里有2个以上组件用这种写法,这点成本就会被公共依赖缓存抹平,整体打包体积差可以忽略。甚至因为写法2减少了重复的箭头函数、重复的props解构代码,最终产物体积还可能略小一点。维护与类型体验差异
用TypeScript开发的话,写法2的类型推导体验好很多:你只需要在外层箭头函数的参数位置做一次props类型标注,内部所有插值都能自动拿到类型提示,不用给每个插值的箭头函数单独标类型。碰到复杂样式逻辑的时候,还可以直接在外层函数体内抽变量、写分支判断,不用把长长的三元表达式全塞在插值占位符里,代码可读性高很多。
写法1的优势是写1-2条简单动态样式的时候更省事,不用额外引入css,也不用套一层函数,代码更短。
选择建议
组件动态样式不超过2条的时候随便选,按自己的写代码习惯来就行;如果动态样式超过3条、或者要写不少基于props、theme的分支逻辑,优先选写法2,性能和维护效率都更好。
内容的提问来源于stack exchange,提问作者TimmNL

