reactjs - React - 将 SCSS“对象”作为属性传递
问题描述
我正在创建一个供个人使用的自定义组件库,并且我想使其可定制。我想在这里使用的方法类似于下面的代码。我不确定这是否是最好的方法,甚至是否可以以这种方式使用它。我很高兴有任何使代码看起来不错的建议。谢谢
组件.tsx
interface IProps {
cssClass: any; <-- what type to put here?
}
export const SomeCustomComponent = (props: IProps) => {
return (
<>
<div className={cssClass}>
<p className={cssClass.header}>Header</p>
<Icon className={cssClass.icon}/>
</div>
</>
)
}
样式.scss
.myComponent {
color: white;
.header { margin-left: 10px; }
.icon { margin-right: 10px; }
}
主要组件.tsx
import styles from './Styles.scss'
const MainComponent = () => {
return (
<>
<SomeCustomComponent cssClass={styles.myComponent}/>
</>
)
}
解决方案
有多种方法可以实现定制样式,我想到了两种方法(以及经过一些研究的第三种方法)。还有其他方法可以做到这一点。前两个选项在没有 CSS-Modules 的情况下执行此操作。第三个是尝试使用 CSS-Modules 解决这个问题。
选项1
将样式从父组件传递给子组件。您可以styles
在父级中动态更新并将其传递给子级。因为您将对象作为道具传递,所以这可能会导致不必要的重新渲染并损害性能。内联样式很好,因为它们很容易动态创建和作为道具传递。它们是传递动态样式的事实上的方式。
import React, { CSSProperties } from 'react';
interface CSSStyles {
[key: string]: CSSProperties;
}
const MainComponent = () => {
const styles: CSSStyles = {
header: { marginLeft: "10px" }, // Dynamically update
icon: { marginRight: "10px" }, // Dynamically update
myComponent: { color: "black" }, // Dynamically update
};
return (
<>
<SomeCustomComponent cssClasses={styles} />
</>
);
};
interface Props {
cssClasses: CSSStyles;
}
const SomeCustomComponent = ({ cssClasses }: Props) => {
return (
<div style={cssClasses.myComponent}>
<p style={cssClasses.header}>Header</p>
<Icon style={cssClasses.icon} />
</div>
);
};
选项 2
您可以将 aclassName
作为字符串传递并在父级中更新它。这需要您在.scss
文件中创建多个类。由于cssClasses
道具在这里传递了一个对象,这也可能导致不必要的重新渲染。如果性能出现问题,您可以对此进行调整。
.tsx
interface CSSStyles {
[key: string]: string;
}
const MainComponent = () => {
const styles: CSSStyles = {
header: "header", // Dynamically change
icon: "icon", // Dynamically change
myComponent: "myOtherComponent", // Dynamically change
};
return (
<>
<SomeCustomComponent cssClasses={styles} />
</>
);
};
interface Props {
cssClasses: CSSStyles;
}
const SomeCustomComponent = ({ cssClasses }: Props) => {
return (
<div className={cssClasses.myComponent}>
<p className={cssClasses.header}>Header</p>
<Icon className={cssClasses.icon} />
</div>
);
};
.scss
.myComponent {
color: white;
.header {
margin-left: 10px;
}
.icon {
margin-right: 10px;
}
}
.myOtherComponent {
color: black;
.header {
margin-left: 100px;
}
.icon {
margin-right: 100px;
}
}
选项 3
一种 CSS 模块特定的方式。看起来你可以:
- 将每个孩子包裹在一个 div 中
- 将 className 作为 props 传递
- 使用 CSS 子组合器
- 创建多个 CSS 类并传递 className(类似于选项 2)。
这些似乎特定于 CSS-Modules,但似乎比选项 1 或 2 更复杂。我不确定 CSS-Modules 的性能影响。
有关参考,请参阅https://stackoverflow.com/a/55082008/9931154和https://stackoverflow.com/a/34036086/9931154。CSS-Modules 文档似乎没有提到与您的问题有关的任何内容。