如何在styled components中正确转义CSS函数避免插值报错?
问题描述
背景
我需要复用同一套CSS样式为两个不同组件添加动画效果,动画逻辑依赖传入AnimatedBox组件的props参数,比如仅当props.right为true时,只对右边框执行动画。我原本以为CSS函数可以实现这个需求,不需要重复编写代码,仅需创建元素并调用函数即可。但多次调整后始终遇到如下报错,且组件运行效果不符合预期:
Functions that are interpolated in css calls will be stringified.
原代码(截断)
const AnimatedBox = props => ( <> {props.absolute ? <MaskWrapper> <BeforeMask {...props}/> <AfterMask {...props}/> </MaskWrapper> : <AnimatedDiv {...props}></AnimatedDiv>} </> ) export default AnimatedBox const commonConfig = css` box-sizing: inherit; position: absolute; content: ''; border: 1px solid transparent; border-radius: 3px; ` const beforeConfig = css` top: 0; left: 0; border-top-color: ${({top}) => `${top && "#60d75a"}`}; border-right-color: ${({right}) => `${right && "#60d75a"}`}; animation: ${expandWidth} 0.25s ease-out forwards, ${expandHeight} 0.25s ease-out 0.25s forwards; ` const afterConfig = css` right: 0; bottom: 0; animation: ${({bottom, left}) => `${ (bottom && left) ? ` ${bottomBorderColor} 0s ease-out 0.5s forwards, ${leftBorderColor} 0s ease-out 0.5s forwards, ${expandWidth} 0.25s ease-out 0.5s forwards, ${expandHeight} 0.25s ease-out 0.75s forwards; ` : ( bottom ? ` ${bottomBorderColor} 0s ease-out 0.5s forwards, ${expandWidth} 0.25s ease-out 0.5s forwards, ${expandHeight} 0.25s ease-out 0.75s forwards; ` : ( left && ` ${leftBorderColor} 0s ease-out 0.5s forwards, ${expandWidth} 0.25s ease-out 0.5s forwards, ${expandHeight} 0.25s ease-out 0.75s forwards; ` ) ) }` }; ` const BeforeMask = styled.div` ${beforeConfig} ` (...)
上述代码中expandWidth、expandHeight、bottomBorderColor等均为关键帧动画,需要了解如何正确编写这类函数并传入目标styled component,避免出现上述报错。
解决方案
按照@jsejcksn的建议,将styled div定义放到组件作用域内,再修改CSS函数显式接收参数,调整部分语法后将所需的props传入函数即可解决问题。
修复后代码
const AnimatedBox = props => { (...) const BeforeMask = styled.div` ${beforeConfig(props.top, props.right)} ` (...) return ( <> {props.absolute ? <MaskWrapper> <BeforeMask {...props}/> <AfterMask {...props}/> </MaskWrapper> : <AnimatedDiv {...props}></AnimatedDiv>} </> )} const beforeConfig = (top, right) => css` top: 0; left: 0; border-top-color: ${top && "#60d75a"}; border-right-color: ${right && "#60d75a"}; animation: ${expandWidth} 0.25s ease-out forwards, ${expandHeight} 0.25s ease-out 0.25s forwards; ` const afterConfig = (bottom, left) => css` right: 0; bottom: 0; animation: ${ (bottom && left) ? css` ${bottomBorderColor} 0s ease-out 0.5s forwards, ${leftBorderColor} 0s ease-out 0.5s forwards, ${expandWidth} 0.25s ease-out 0.5s forwards, ${expandHeight} 0.25s ease-out 0.75s forwards; ` : ( bottom ? css` ${bottomBorderColor} 0s ease-out 0.5s forwards, ${expandWidth} 0.25s ease-out 0.5s forwards, ${expandHeight} 0.25s ease-out 0.75s forwards; ` : ( left && css` ${leftBorderColor} 0s ease-out 0.5s forwards, ${expandWidth} 0.25s ease-out 0.5s forwards, ${expandHeight} 0.25s ease-out 0.75s forwards; ` ) ) } `
内容的提问来源于stack exchange,提问作者lobo09
相关产品推荐
相关产品推荐

