我在这里有一个游乐场:https://codesandbox.io/s/736v9vjzw1
const Something = ({ classes, children, variant }) => {
return (
<div className={classes.someThing}>
<p> I'm some thing </p>
<SomeOtherThing />
<SomeOtherThing> I have some children </SomeOtherThing>
<SomeOtherThing> I have some children </SomeOtherThing>
<SomeOtherThing> I have some children </SomeOtherThing>
</div>
);
};
const styles = {
someThing: {
color: "green",
border: "solid 2px black",
margin: 30,
"& $someOtherThing": {
backgroundColor: "pink" // Doesn't work
},
"& p": {
fontWeight: "bold" //This works but is too broad
}
}
};
我在这里遇到一种情况,我想为SomeOtherThing
中的所有SomeThing
设置样式。
我可以使用& p
选择器来选择p
元素-但我不喜欢这样。它将为我周围的任何随机p
设置样式-我不想查看组件定义的内部以查找其顶级元素是什么。
我该怎么做?像& SomeOtherElement
之类的东西。
此方法的实际应用是,在某些地方我想SomeOtherElement
显示block
,而在其他地方inline-block
。
答案 0 :(得分:4)
我将扩展SomeOtherThing
组件以接受className并将其添加到div
(如果存在)。这也将在生产设置中起作用,其中将类名最小化为例如。 .t-0-root
。
这是一个分叉的游乐场:https://codesandbox.io/s/zlzx277zzm,显示了如何使用它。
const SomeOtherThing = ({ classes, children, className }) => {
return (
<p className={`${classes.someOtherThing} ${className && className}`}>
I'm another thing {children}
</p>
);
};
我很可能会使用包classnames
来有条件地呈现类名,而不是字符串插值。
const Something = ({ classes, children, variant }) => {
return (
<div className={classes.someThing}>
<p> I'm some thing </p>
<SomeOtherThing />
<SomeOtherThing className={classes.someOtherThing}>
I have some children
</SomeOtherThing>
<SomeOtherThing className={classes.someOtherThing}>
I have some children
</SomeOtherThing>
<SomeOtherThing className={classes.someOtherThing}>
I have some children
</SomeOtherThing>
</div>
);
};
const styles = {
someThing: {
color: "green",
border: "solid 2px black",
margin: 30
},
someOtherThing: {
backgroundColor: "pink"
}
};
答案 1 :(得分:0)
非常简单,在您的someThing
CSS代码中,选择类名为p
的{{1}}元素,并在顶部someOtherThing
使用not()
CSS操作级别,请参见以下代码:
p
和
const styles = {
someThing: {
color: "green",
border: "solid 2px black",
margin: 30,
"& [class*='SomeOtherThing']": {
backgroundColor: "pink" //
},
"& :not([class*='SomeOtherThing'])": {
fontWeight: "bold" // Just for top level p
}
}
};
此方法的工作方式是,通过为const SomeOtherThing = ({ classes, children }) => {
return (
<p className={classes.root}> I'm another thing {children} </p>
);
};
提供任何jss类,它将把dom元素呈现为类似以下内容:
SomeOtherThing
与 <p class="SomeOtherThing-root-0-1-2"> I'm another thing I have some children </p>
] attribute selector匹配的
。
您应注意,该选择器也将适用于任何更深层的嵌套[class*='SomeOtherThing'
。
答案 2 :(得分:-1)
CSS的“层叠”方面的一个问题是它破坏了React的组件模型。但是在React中,您始终可以创建一个包装器或高阶组件,该组件将返回另一个带有一些预定义道具的组件,就像工厂函数一样:
const Something = props => {
return (
<div className={props.className}>
// ...
</div>
)
}
const SomethingInline = props => {
return <Something className='display-inline' {...props} />
}
const SomethingBlock = props => {
return <Something className='display-block' {...props} />
}
const App = () => {
return (
<div>
<SomethingInline />
<SomethingBlock />
<SomethingBlock> I have children </SomethingBlock>
</div>
)
}
创建一个仅适用于组件的这些特定版本的类,而不是使用&
选择器来定义样式。这样,就避免了CSS的全局范围,您可以创建描述其自身样式的这类声明性组件,但不需要您显式传递类名。