【问题标题】:What is the preferred way of passing styles to children in React & Emotion JS?在 React & Emotion JS 中将样式传递给孩子的首选方式是什么?
【发布时间】:2021-03-24 11:57:07
【问题描述】:

在使用react-jss 几年后,我才刚刚开始使用emotion。我正在努力寻找一个很好的例子的一件事是将(一些,可能是动态的)样式传递给子组件。在react-jss 中,这非常简单:

// In SomeParent.jsx
... imports etc ...

const useStyles = createUseStyles({
  custom: {
    color: 'blue',
  },
})

export const CustomBody = () => {
  const classes = useStyles()
  return <Body className={classes.custom}>some text</Body>
} 

// In Body.jsx
... imports etc...

const useStyles = createUseStyles({
  body: {
    fontSize: 16,
    color: 'black',
  },
})

const Body = ({ children, className }) => {
  const classes = useStyles()
  return (
    <p
      className={clsx(
        classes.body,
        className,
      )}
    >
      {children}
    </p>
  )
}

本质上,父组件可以创建样式并通过 prop(通常为 className )将任意数量的相关类名传递给子组件,然后子组件可以在自己的 className 属性中使用它们,并将它们与任何其他样式结合起来子组件需要。

情绪确实允许同样的事情,但我不知道他们如何期望你这样做。

在子方面的语义上,styled tagged template literal 似乎接受了emotion 样式并将className 属性传递给子级,然后它的工作方式与在 react-jss 中的工作方式相同。但是,我发现styled 语法非常丑陋且难以解析。我宁愿不用styled HOC 包装的子组件填充我的父文件。

从功能上讲,似乎传递了我自己的 emotion 样式属性并在子组件中组合这些样式最接近于 react-jss,但我在情感文档中找不到任何示例表明这是他们的东西期待你做。它不是 FORBIDDEN 或任何东西,只是没有突出显示。像下面这样的东西有意义吗?

// In SomeParent.jsx
... imports etc ...

export const CustomBody = () => {
  return <Body customStyles={css`color: blue`}>some text</Body>
}

// In Body.jsx
... imports etc...

const bodyStyles = css`
  font-size: 16px;
  color: black;
`
const Body = ({ children, customStyles }) => {
  return (
    <p
      css={css`
        ${bodyStyles};
        ${customStyles};
      `}
    >
      {children}
    </p>
  )
}

composition documentation 明确表明这将起作用(并且确实如此),但它并没有像styled 文档那样专门展示从一个组件到另一个组件的传递样式。这对我来说感觉更好,但我担心the note in the string styles documentation 指出css 不返回类字符串,而是返回一个完整的对象,该对象“在低层次上被情感理解”。如果emotion 没有记住这个对象(我自己还没有测试过),那么我最终会得到一堆不必要的重新渲染。我可以记住作为该对象一部分包含的类名字符串,但我也不确定这是否一致。

最后可能相关的是class names API。看起来这将允许我创建一个样式并将其作为className 字符串传递给子组件(很像react-jss 并避免重新渲染问题),但同样,必须包装每个子组件在ClassNames 组件中接受来自父级的样式,然后处理渲染函数似乎很疯狂。

我只是在这里遗漏了什么吗?全世界都接受styled 并且样式化的组件模式就是使用这些东西的方式吗?请让我知道您是如何解决此问题的,或将我指向我看过的文档。非常感谢!

【问题讨论】:

    标签: reactjs emotion css-in-js


    【解决方案1】:

    如果以后有人发现这篇文章,我会进行自己的测试,比较每种方法在创建 1000 个标签并根据它们的索引为它们着色时的性能。

    styled 的性能最高,ClassNames 的性能第二好(其最佳性能通常与styled 性能的低端相当)。直接传递css 标记的模板字面量比其他两个都差得多,性能比styled 的最差性能差1.5 到2 倍。

    通过传递道具进行有条件的样式设置绝对比静态样式慢,并且使用prop filteringstyled 只会降低性能而不是过滤(如果这是一个潜在的问题,这可能是一个很好的权衡来防止不必要的重新渲染)。

    【讨论】:

    • 我可能是错的,它可能值得测试,但我认为直接将对象传递给 css prop 可能会更高效,因为您不需要 css`` 函数。例如,只需将 {color: 'black'} 传递给 css prop 即可。此外,如果您在组件之外定义 css 可以加快速度。就像 const myStyle =csscolor: black 然后通过它。当您直接使用 css`` 传递标记模板时,您实际上是在调用一个函数,该函数生成一个情感对象,以便在渲染期间理解。在您的示例中,我会执行 css={[bodyStyles, customStyles]}
    • 这样可以避免调用 css 和使用字符串插值。这是来自情感网站的引用,以示例具有 css 功能。 “来自@emotion/react 的css 不返回计算出的类名字符串。该函数返回一个包含计算出的名称和扁平样式的对象。”emotion.sh/docs/css-prop(向下滚动到字符串样式)。 styled 很可能性能更高,因为您在组件本身之外声明了它。
    猜你喜欢
    • 2019-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-17
    • 2019-05-07
    • 2018-12-01
    • 2020-04-10
    • 1970-01-01
    相关资源
    最近更新 更多