Javascript 如何添加样式(如边距)以响应组件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/49825386/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to add style - like margin - to react component?
提问by Daniel Hilgarth
So, expect two simple components that I have built:
因此,请期待我构建的两个简单组件:
import {Input} from 'semantic-ui-react';
import {Select} from 'semantic-ui-react';
const CategoriesDropdown = ({categories, onCategorySelected, selectedCategory}) => {
const handleChange = (e, {value})=>{
onCategorySelected(value);
};
return (
<Select placeholder="Select category" search options={categories} onChange={handleChange} value={selectedCategory} />
);
};
const IdentifiersInput = ({identifiers, onIdentifiersChanged}) => {
return (
<Input placeholder="Enter identifiers..." value={identifiers} onChange={onIdentifiersChanged}/>
);
};
Nothing fancy so far.
到目前为止没有什么花哨的。
But now, I am building another component that displays those two in a flexbox row:
但是现在,我正在构建另一个组件,在 flexbox 行中显示这两个:
<Box>
<CategoriesDropdown categories={categories} selectedCategory={selectedCategoryId}
onCategorySelected={this.selectCategory}/>
<IdentifiersInput identifiers={identifiers} onIdentifiersChanged={this.changeIdentifiers}/>
</Box>
Unfortunately they are both displayed right next to each other without any margin in between.
不幸的是,它们都紧挨着显示,中间没有任何边距。
Usually, I would just add a margin-leftstyle to the second element, but because it is a React component, that doesn't work. Using style={{marginLeft: '20px'}}doesn't work as well, because the IdentifiersInputcomponent doesn't use it.
I know that I can fix it by doing this: <Input style={style} ...inside the IdentifiersInputcomponent.
However, this seems to be a very tedious way of achieving this goal. Basically, I have to add this to every single component I am writing.
I clearly must be missing something here. How am I supposed to apply such layout CSS properties to React components?
通常,我只会margin-left为第二个元素添加一个样式,但因为它是一个 React 组件,所以不起作用。使用style={{marginLeft: '20px'}}也不起作用,因为IdentifiersInput组件不使用它。
我知道我可以通过这样做来修复它:<Input style={style} ...在IdentifiersInput组件内部。
然而,这似乎是实现这一目标的一种非常乏味的方式。基本上,我必须将它添加到我正在编写的每个组件中。
我显然在这里遗漏了一些东西。我应该如何将这样的布局 CSS 属性应用于 React 组件?
采纳答案by agm1984
I think I understand.
我觉得我懂了。
1) Applying CSS directly to React Components does not work--I can confirm that.
1) 将 CSS 直接应用于 React 组件是行不通的——我可以确认这一点。
2) Passing props down to the low level elements is tedious, confirmed but viable.
2) 将道具传递给低级元素是乏味的,确认但可行的。
Notice hasMarginprop:
注意hasMargin道具:
<Box>
<CategoriesDropdown
categories={categories}
selectedCategory={selectedCategoryId}
onCategorySelected={this.selectCategory}
/>
<IdentifiersInput
identifiers={identifiers}
onIdentifiersChanged={this.changeIdentifiers}
hasMargin
/>
</Box>
Possible input:
可能的输入:
const IdentifiersInput = ({identifiers, onIdentifiersChanged, className, hasMargin }) => {
return (
<Input
className={className}
placeholder="Enter identifiers..."
value={identifiers}
onChange={onIdentifiersChanged}
style={hasMargin ? ({ marginLeft: '0.8rem' }) : ({})}
/>
);
};
NOTE: I do not like style as much as I like adding an additional class because classes can be adjusted via media queries:
注意:我不喜欢样式,因为我喜欢添加额外的类,因为类可以通过媒体查询进行调整:
const IdentifiersInput = ({identifiers, onIdentifiersChanged, className, hasMargin }) => {
const inputPosition = hasMargin ? `${className} margin-sm` : className
return (
<Input
className={inputPosition}
placeholder="Enter identifiers..."
value={identifiers}
onChange={onIdentifiersChanged}
/>
);
};
If you find inputPositiontoo verbose as shown above:
如果你发现inputPosition如上图所示过于冗长:
className={hasMargin ? `${className} margin-sm` : className}
3) You could accomplish it using a divider Component, sacreligious yet rapidly effective
3)您可以使用分隔器组件来完成它,神圣但快速有效
<Box>
<CategoriesDropdown
categories={categories}
selectedCategory={selectedCategoryId}
onCategorySelected={this.selectCategory}
/>
<div className="divider" />
<IdentifiersInput
identifiers={identifiers}
onIdentifiersChanged={this.changeIdentifiers}
/>
</Box>
You can use media queries and control padding at any breakpoints if desired.
如果需要,您可以在任何断点处使用媒体查询和控制填充。
4) CSS pseudo-elements or pseudo-classes, I don't see any mention of them in answers so far.
4) CSS 伪元素或伪类,到目前为止,我在答案中没有看到任何提及它们。
MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes
CSS Tricks: https://css-tricks.com/pseudo-class-selectors/
Usually, when you have a random collection of DOM elements, you can calculate a way using CSS to wrangle them into the correct position. The list of available pseudo-classes is in that MDN link. It honestly helps to just look at them and reason about potential combinations.
通常,当你有一个随机的 DOM 元素集合时,你可以计算出一种使用 CSS 将它们纠缠到正确位置的方法。可用伪类的列表在该 MDN 链接中。老实说,看看它们并推理潜在的组合是有帮助的。
My current issue is I don't know what is in <Box />other than it probably has a div with display: flex;on it. If all we have to go on is that and the div is called <div className="Box">, maybe some CSS like this will fix it:
我目前的问题是我不知道<Box />除了它上面可能有一个 div 之外还有display: flex;什么。如果我们所要做的就是这样并且 div 被调用<div className="Box">,也许像这样的一些 CSS 会修复它:
.Box {
display: flex;
}
.Box:first-child {
margin-right: 0.8rem;
}
This is why it is extremely important to know exactly what the surrounding elements will or can be, and exactly which CSS classes/IDs are nearby. We are basically trying to hook into something and correctly identify the left child in Box and add margin to the right of it, or target the right child and add margin to the left of it (or depending on everything, target both and split the additional margin onto both).
这就是为什么准确了解周围元素将是什么或可以是什么,以及附近有哪些 CSS 类/ID 非常重要的原因。我们基本上是在尝试挂钩并正确识别 Box 中的左孩子并在其右侧添加边距,或定位右孩子并在其左侧添加边距(或取决于所有内容,同时定位并拆分额外的两者的边距)。
Remember there is also ::beforeand ::after. You are welcome to get creative and find a solution that involves position:relativeand position: absoluteand adds no markup.
记住还有::beforeand ::after。欢迎您发挥创意并找到不涉及position:relative和position: absolute不添加标记的解决方案。
I will leave my answer like that for now, because I think either you already thought about pseudo-selectors, or you will quickly find something that works :)
我现在就这样留下我的答案,因为我认为你要么已经考虑过伪选择器,要么很快就会找到有用的东西:)
That or the divider is actually quite viable. The fact you can use media queries alleviates you from concern of future management or scalability of the components. I would not say the same about <div style={{}} />.
那个或分隔符实际上是非常可行的。您可以使用媒体查询这一事实使您无需担心组件的未来管理或可扩展性。我不会说同样的话<div style={{}} />。
回答by trixn
As your component specializes another single component it would be a good practice to pass any props your wrapper does not care for to the wrapped component. Otherwise you will loose the ability to use the api of the original <Input>component including passing styles to it:
由于您的组件专门用于另一个单个组件,因此将您的包装器不关心的任何道具传递给被包装的组件是一个很好的做法。否则,您将无法使用原始<Input>组件的 api,包括向其传递样式:
const IdentifiersInput = ({identifiers, onIdentifiersChanged, ...props}) = (
<Input
{...props}
placeholder="Enter identifiers..."
value={identifiers}
onChange={onIdentifiersChanged}
/>
);
There may be valid cases where you explicitly want to prevent users to be able to pass props to the wrapped component but that does not look like one of those to me.
在某些情况下,您可能明确希望阻止用户将 props 传递给被包装的组件,但这在我看来并不像其中之一。
I clearly must be missing something here. How am I supposed to apply such layout CSS properties to React components?
我显然必须在这里遗漏一些东西。我应该如何将这样的布局 CSS 属性应用于 React 组件?
You did not miss something. A react component has no generic way to be styled because it is no DOM element. It can have a very complicated and nested DOM representation or no representation at all. So at some point you as the designer of the component have to decided where the styles, ids and class names should be applied. In your case it is as easy as passing these props down and let the <Input>and <Select>component decide. I find that to be quite elegant rather than tedious.
你没有错过什么。React 组件没有通用的样式设置方式,因为它不是 DOM 元素。它可以有一个非常复杂和嵌套的 DOM 表示或根本没有表示。因此,在某些时候,作为组件的设计者,您必须决定应该在哪里应用样式、ID 和类名。在您的情况下,就像传递这些道具并让<Input>和<Select>组件决定一样简单。我觉得这很优雅而不是乏味。
回答by José Del Valle
I see several ways to do it, but the easiest I see would be to pass a className to IdentifiersInput like so:
我看到了几种方法,但我看到的最简单的方法是将 className 传递给 IdentifiersInput,如下所示:
<IdentifiersInput className="marginLeft" identifiers={identifiers} onIdentifiersChanged={this.changeIdentifiers}/>
Inside IdentifiersInput I would just set that class to the Input:
在 IdentifiersInput 中,我只需将该类设置为 Input:
const IdentifiersInput = ({identifiers, onIdentifiersChanged, className}) => {
return (
<Input className={className} placeholder="Enter identifiers..." value={identifiers} onChange={onIdentifiersChanged}/>
);
};
Semantic UI's Input element can receive a className prop. I would then just use CSS or SCSS to add styles to that particular class. In this case, the margin you want.
语义 UI 的 Input 元素可以接收一个 className 属性。然后我将只使用 CSS 或 SCSS 向该特定类添加样式。在这种情况下,您想要的保证金。

