使用样式组件定位本机dom元素<input /> ...

时间:2017-12-13 22:16:37

标签: css reactjs styled-components

我无法让我的样式化组件对React组件中包含的<input />进行更改。在Dev Tools中,我可以看到我试图覆盖的样式:

.ui.input input {...}

我认为包装组件需要将className传递给输入,即

<input className = {this.props.className} ..> ... </input>

但我无法使用或不使用该方式来覆盖。我将在下面提供一些片段。

//styled component
const StyledSearch = styled(Searchbar)`
  &.ui.input input{
    border: 0px !important;
  }
`;


class SearchBar extends Component {
...
render() {
const style = {
  display: this.state.showResults ? 'block' : 'none',
  maxHeight: 500,
  overflowY: 'scroll',
};
return (
  <div className="ui search fluid" ref="container">
    <div
      className={`ui icon fluid input ${this.props.loading ? 'loading' : ''}`}>
      <input type="text"
        placeholder={this.props.placeholder}
        onFocus={this.focus}
        className = {this.props.className}
        value={this.props.value}
        onChange={this.props.onChange}/>
      <i className="search icon"></i>
    </div>
    <div
      className="results"
      style={style}>

      {
        this.props.results.map((result, index) => (
            <a
              className="result"
              key={index}
              onClick={this.select.bind(this, result)}>
              <div className="content">
                {
                  result.get('image') ?
                  (
                    <div className="image">
                      <img src={result.get('image')} style={{ maxWidth: 50 }}/>
                    </div>
                  ) : null
                }
                <div className="title">
                  {result.get('title')}
                </div>
                <div className="description">
                  {result.get('description')}
                </div>
              </div>
            </a>
          )
        )
      }
    </div>
  </div>
);}}

3 个答案:

答案 0 :(得分:1)

据我所知,您需要将使用styled-components生成的样式应用于包装元素。这是由于.ui.input input外部风格的特殊性。这意味着我们不能简单地使用新样式定位input元素,因为.ui.input input选择器更具体并且优先。这是一个简单的CSS示例,显示.ui.input input选择器的特异性如何优先于input样式:

.ui.input input {
  border:2px solid red !important;
}

input {
  border: 0px !important;
}
<div class="ui input">
  <input />
</div>

同样的问题在您的案例中发挥作用。在下面的示例中,我创建了一个新的Wrapper组件,其样式为:

&.ui.input input {
  border: 0px !important;
  font-size: 24px;
}   

定义了它。这会以更具体的方式定位内部input元素,以覆盖外部样式。

import React from 'react';
import ReactDOM from 'react-dom';
import styled from 'styled-components';

class InputWrapper extends React.Component {

  render() {
     const Wrapper = styled.div`
       &.ui.input input {
         border: 0px !important;
         font-size: 24px;
       }
     `;

    return(
      <Wrapper className="ui input">
        <input type="text" placeholder="Input" />
      </Wrapper>
    )
  }
}


ReactDOM.render(
    <InputWrapper />, 
    document.getElementById("app")
);

这是一个WebpackBin示例。

答案 1 :(得分:1)

基本上,styled-components为任何调用styled函数的DOM或React组件创建新的唯一类名(换句话说,一个新的命名空间)。

这意味着,当您使用styled(SearchBar)时,styled-components包装SearchBar组件并将唯一的类名称附加到其根DOM。然后它将该唯一类名传递给后代DOM和组件(在您的情况下,嵌套divinputa)。

要使此方法起作用,您的根DOM必须具有可以从外部配置的className。这就是为什么,styled-components期望根DOM具有定义${this.props.className}作为其className道具的值。如果你的组件缺少这个,styled-components将无法创建一个新的命名空间,它可以用来应用特定的样式。

因此,要使您的技术发挥作用,必须将${this.props.className}指定为className <{1}}的根div所定义的值SearchBar之一< /强>

Working Demo

如果您无法访问SearchBar,则可以使用其他组件进行包装。这个过程的开销是,你必须使用额外的DOM级别

Working Demo

答案 2 :(得分:0)

当前在第4版中,您可以做到

const Input = styled.input`
  border:2px solid red !important;
`;

它将使用SC className呈现为本机输入