如何向@emotion/react的css样式传递自定义样式Props?
解决方案:给Emotion样式传递Props
当然可以实现给ElementWrapper传递样式Props,核心是把静态样式改成接收参数的样式函数,或者在组件层动态组合样式。以下是适配你架构的两种可行方案:
方案1:将样式定义为接收Props的函数
直接在styles.ts里把ElementWrapper改成带参数的函数,让它能根据传入的Props生成动态样式:
修改styles.ts
import { css } from '@emotion/react'; import { ElementProps } from './types'; export const ElementWrapper = ({ marginRight }: Pick<ElementProps, 'marginRight'>) => css` border: 1px solid red; ${marginRight === false ? 'margin-right: 0;' : ''} `;
修改web.tsx
在组件中接收样式Props,传递给样式函数:
import { ElementProps } from './types'; import { ElementWrapper } from './styles'; import { PropsWithChildren } from 'react'; export const Element = ({ children, marginRight, ...rest }: PropsWithChildren<ElementProps>) => { return ( <SOME_ELEMENT css={ElementWrapper({ marginRight })} {...rest}> {children} </SOME_ELEMENT> ); };
补充:跨端共享类型
在types.ts里统一定义样式相关的Props,确保web和native端复用同一类型:
export interface ElementProps { // 你的其他组件Props marginRight?: boolean; }
方案2:用cx函数动态合并样式
如果需要更灵活的样式组合(比如多个动态样式开关),可以用Emotion的cx函数合并基础样式和动态样式片段:
修改styles.ts
拆分基础样式和动态样式片段:
import { css } from '@emotion/react'; export const ElementBase = css` border: 1px solid red; `; export const ElementNoMarginRight = css` margin-right: 0; `;
修改web.tsx
根据Props判断是否合并对应样式:
import { ElementProps } from './types'; import { ElementBase, ElementNoMarginRight } from './styles'; import { PropsWithChildren } from 'react'; import { cx } from '@emotion/react'; export const Element = ({ children, marginRight, ...rest }: PropsWithChildren<ElementProps>) => { const elementStyles = cx( ElementBase, marginRight === false && ElementNoMarginRight ); return ( <SOME_ELEMENT css={elementStyles} {...rest}> {children} </SOME_ELEMENT> ); };
为什么之前的方法无效?
你之前直接传递Props给SOME_ELEMENT无法穿透到样式,是因为原来的ElementWrapper是静态生成的样式对象,不是可接收参数的函数,无法感知组件层的Props变化。只有把样式定义为函数,或者在组件层根据Props动态组合样式,才能实现样式的动态调整。
内容的提问来源于stack exchange,提问作者Josh
相关产品推荐
相关产品推荐

