【问题标题】:Is it possible to style a checkbox's child based on the checkbox's state without using ternary in Styled Components?是否可以在不使用样式组件中的三元组的情况下根据复选框的状态设置复选框的子项样式?
【发布时间】:2019-08-23 00:46:34
【问题描述】:

我正在尝试使用 Styled Components 来设置该组件的样式,但我的解决方案似乎很老套。使用 Styled Components 对该组件进行样式设置的最佳实践是什么?

使用纯 HTML 和 CSS,我可以创建:

HTML:

<label>
  <input type="checkbox" value="s1"/>
  <div class="container">s1</div>
</label>
<label>
  <input type="checkbox" value="s2"/>
  <div class="container">s2</div>
</label>
<label>
  <input type="checkbox" value="s3"/>
  <div class="container">s3</div>
</label>
<label>
  <input type="checkbox" value="s4"/>
  <div class="container">s4</div>
</label>

CSS:

input[type=checkbox] {
  position: absolute;
  width: 0;    
}

.container {
  width: 5em;
  border: solid #aaa 1px;
  background: #fff
  color: #000;
}
.container:hover {
  background: #999;
}  

.container:active {
  background: #333;
  color:#fff
}

input[type=checkbox]:checked + .container {   
  background: #000;
  color: #fff;
}    

input[type=checkbox]:checked + .container:hover {
  background: #ddd;
}  

input[type=checkbox]:checked + .container:hover:active {
  background: white;
  color: black;
}  

使用 React 组件和 Styled Components,我也可以创建它,但我不喜欢使用两个不同的 Styled Components 和三元组来完成我在 CSS 中使用 input[type=checkbox]:checked + .container 可以完成的事情。

import React, { useState } from 'react';
import styled from 'styled-components'

function Test() {
  const [selectedStations, setSelectedStations] = useState([]);  

  const Input = styled.input`
    position: absolute;
    width: 0;    
  ` 
  const UncheckedContainer = styled.div` 
    width: 5em;    
    border: solid #aaa 1px;
    background: #fff;
    color: #000;

  &:hover {
    background: #999;
  }  

  &:active {
      background: #333;
      color: #fff;
  }
  `
  const CheckedContainer = styled.div`
    width: 5em;
    border: solid black 1px;
    background: #000;
    color: #fff;

  &:hover {
    background: #ddd;
  }  

  &:active {
      background: #fff;
      color: #000;
  }  
  `

  function selectStations(e) {    
    let station = e.target.value;
    const s = [...selectedStations]
    const stationIndex = s.indexOf(station)

    if (stationIndex > -1) {
      s.splice(stationIndex, 1);
    } else {
      s.push(station);
      s.sort();
    }

    setSelectedStations(s)
  };


  return (
    <div>
        {new Array(4).fill('').map((v, i) =>{

          let checked = selectedStations.indexOf(`s${i+1}`) > -1         

          return(
            <label key={`station${i + 1}`}>
            <Input              
              type="checkbox"
              value={`s${i+1}`}
              checked={checked}
              onChange={(e)=>selectStations(e)}              
            />

            {checked ? 
              <CheckedContainer>
                  {`s${i+1}`}
              </CheckedContainer>            
            : 
              <UncheckedContainer>
                  {`Station ${i+1}`}
              </UncheckedContainer>
            }


          </label>
          )}
        )}
    </div>
  )
}

export default Test;

是否可以稍微清理一下但仍然使用样式化组件?

【问题讨论】:

    标签: javascript css reactjs styled-components


    【解决方案1】:

    您可以将复选框的状态放在变量中并将其传递给样式组件,例如:

    <StyledComponent isChecked={isChecked} />
    

    然后在样式化组件中:

    const StyledComponent = styled.input`
    
     color: ${props => props.isChecked ? '#fff' : '#000'};
    
    `
    

    .. 以此类推作为背景颜色和边框。

    【讨论】:

    • 您仍然需要使用三元运算符(我不认为这很混乱),但现在只有一个样式组件,而不是两个用于选中/未选中的组件。
    • 这回答了我的问题。它将三元从 render 函数移到 Styled Component 函数,我认为这使代码更易于阅读。它还减少了我最初必须使组件工作的样式数量。
    【解决方案2】:

    您可以访问 styled-component 内的 props,也可以使用 sass 之类的嵌套来定位子级。

    const Checkbox = styled.label`
      postion: relative;
      input[type="checkbox"] {
        // style here
      }
      .inner-checkbox {
        color: ${props => props.checked ? "red" : "blue"};
        // style here
      }
    `
    
    const List = props => {
      return props.list.map(item => (
        <Checkbox key={item.id} checked={item.checked}>
          <input checked={item.checked} type="checkbox" onChange={this.updateState} />
          <div className="inner-checkbox" />
        </Checkbox>
      ))
    }
    

    我强烈避免的另一件事是在另一个组件中创建样式化的组件。

    【讨论】:

    • 我是自学成才的,所以你能解释一下为什么你建议避免在另一个组件中使用样式组件吗?
    猜你喜欢
    • 2010-12-12
    • 1970-01-01
    • 2020-02-25
    • 1970-01-01
    • 2010-11-07
    • 2012-02-10
    • 1970-01-01
    • 2013-06-09
    • 1970-01-01
    相关资源
    最近更新 更多