emotion与react-beautiful-dnd结合使用css prop设置条件样式不生效问题
问题根因
react-beautiful-dnd在拖拽进行过程中,会给被拖拽元素动态注入内联style的transform属性用于控制拖拽位移,你直接在拖拽根元素上通过css prop定义的transform样式优先级低于内联样式,因此会被覆盖,仅在拖拽结束、rbd移除内联transform时才会生效。
解决方案
1. 无冲突稳妥方案(最推荐)
不需要调整样式优先级,直接把旋转样式作用在拖拽容器的内层子元素上,完全避开和rbd给外层拖拽元素添加的transform属性冲突:
<Element> {(provided, snapshot) => ( <div ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps} > {/* 内层元素加旋转,不会和外层rbd的transform冲突 */} <div css={{ display: 'flex', color: snapshot.isDragging ? 'red' : 'black', transform: snapshot.isDragging ? 'rotate(15deg)' : 'none', }}> {/* 拖拽内容 */} </div> </div> )} </Element>
2. 不新增DOM的快速修复
如果不想额外嵌套DOM节点,可以手动合并rbd的位移transform和自定义旋转效果,同时提升优先级覆盖内联样式:
<Element> {(provided, snapshot) => ( <div ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps} css={{ display: 'flex', color: snapshot.isDragging ? 'red' : 'black', transform: snapshot.isDragging ? `${provided.draggableProps.style?.transform || ''} rotate(15deg) !important` : 'none', }} > {/* 拖拽内容 */} </div> )} </Element>
性能优化方案
你提到的三元运算符性能开销实际非常小,几乎可以忽略。真正可能造成不必要重渲染的是每次渲染都重新创建css对象的行为,可以通过抽离静态样式、类名切换来优化:
import { css, cx } from '@emotion/css'; // 静态样式抽离到组件外部,避免每次渲染重复创建 const baseInnerStyle = css` display: flex; color: black; `; const draggingInnerStyle = css` color: red; transform: rotate(15deg); `; <Element> {(provided, snapshot) => ( <div ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps} > <div className={cx(baseInnerStyle, snapshot.isDragging && draggingInnerStyle)}> {/* 拖拽内容 */} </div> </div> )} </Element>
这种写法仅在拖拽状态变化时切换类名,减少了重复的样式计算开销,性能更优。
内容的提问来源于stack exchange,提问作者HigoChumbo
相关产品推荐
相关产品推荐

