我可以 select 一个类型的所有 React 组件,而无需为每个组件分配 class 吗?
Can I select all react components of a type, without assigning a class to each one?
我这里有个游乐场: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
}
}
};
我有一种情况,我想在我的 SomeThing
中设置所有 SomeOtherThing
的样式。
我可以使用 & p
select 或 select p
元素 - 但我不喜欢这样。它会为我周围的任何随机 p
设置样式 - 而且我不想查看组件定义内部来查找它的顶级元素是什么。
我该怎么做?类似于 & SomeOtherElement
.
这在现实世界中的应用是,在某些地方我想 SomeOtherElement
显示 block
而在其他地方 inline-block
。
我将扩展 SomeOtherThing
组件以接受 class 名称并将其添加到 div
(如果存在)。这也适用于生产设置,其中 class 名称被缩小为例如.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
有条件地呈现 class 名称而不是字符串插值。
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"
}
};
很简单,在您的 someThing
CSS 代码中 select p
元素带有 class someOtherThing
class在顶层为 p
命名并使用 not()
CSS 操作,请参见以下代码:
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>
);
};
它的工作方式是,通过给 SomeOtherThing
任何 jss class,它会将 dom 元素呈现为类似于:
<p class="SomeOtherThing-root-0-1-2"> I'm another thing I have some children </p>
[class*='SomeOtherThing'
] attribute selector 将匹配。
您应该注意,此 selector 也将适用于任何更深的嵌套 SomeOtherThing
s。
"cascading" CSS 方面的一个问题是它有点破坏了 React 的组件模型。但是在 React 中,你总是可以创建一个包装器或高阶组件,returns 另一个带有一些预定义的道具,有点像工厂函数:
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>
)
}
不要使用 &
选择器来定义您的样式,而是创建一个仅适用于组件的这些特定版本的 class。通过这种方式,避免了 CSS 的全局范围,您可以创建这些描述自己样式的声明性组件,但不需要您显式传递 class 名称。
我这里有个游乐场: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
}
}
};
我有一种情况,我想在我的 SomeThing
中设置所有 SomeOtherThing
的样式。
我可以使用 & p
select 或 select p
元素 - 但我不喜欢这样。它会为我周围的任何随机 p
设置样式 - 而且我不想查看组件定义内部来查找它的顶级元素是什么。
我该怎么做?类似于 & SomeOtherElement
.
这在现实世界中的应用是,在某些地方我想 SomeOtherElement
显示 block
而在其他地方 inline-block
。
我将扩展 SomeOtherThing
组件以接受 class 名称并将其添加到 div
(如果存在)。这也适用于生产设置,其中 class 名称被缩小为例如.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
有条件地呈现 class 名称而不是字符串插值。
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"
}
};
很简单,在您的 someThing
CSS 代码中 select p
元素带有 class someOtherThing
class在顶层为 p
命名并使用 not()
CSS 操作,请参见以下代码:
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>
);
};
它的工作方式是,通过给 SomeOtherThing
任何 jss class,它会将 dom 元素呈现为类似于:
<p class="SomeOtherThing-root-0-1-2"> I'm another thing I have some children </p>
[class*='SomeOtherThing'
] attribute selector 将匹配。
您应该注意,此 selector 也将适用于任何更深的嵌套 SomeOtherThing
s。
"cascading" CSS 方面的一个问题是它有点破坏了 React 的组件模型。但是在 React 中,你总是可以创建一个包装器或高阶组件,returns 另一个带有一些预定义的道具,有点像工厂函数:
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>
)
}
不要使用 &
选择器来定义您的样式,而是创建一个仅适用于组件的这些特定版本的 class。通过这种方式,避免了 CSS 的全局范围,您可以创建这些描述自己样式的声明性组件,但不需要您显式传递 class 名称。