如何在样式化组件中定义className

fli*_*m57 2 reactjs styled-components

我正在忙于重构React项目以使用样式化的组件。目前正在使用SASS。因此,我有一个工作组件:

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

const MainNavDiv = styled.div`
  display: none;
  font-weight: 300;
  font-size: 1.7rem;
  background-color: #F5F5F5;
  grid-column: 1 / span 2;
  grid-row: 2 / span 1;
  border-top: #D3D3D3 solid 1px;
  border-bottom: #D3D3D3 solid 1px;
  z-index: 3;
  @media (min-width: 51rem) {
    display: block;
  }
`;

const Ul = styled.ul`
  list-style-type: none;
  margin: 0;
  padding: 0;
`;

const Li = styled.li`
  border-bottom: 1px dotted #D3D3D3;
  text-indent: 3rem;
  padding: .5rem 0 .5rem 0;
  height: 2.1rem;
  & :last-child {
    border: none;
  }
  & a {
    text-decoration: none;
    color: #000;
    WebkitTransition: text-indent 0.5s ease, color 0.5s ease;
    MozTransition: text-indent 0.5s ease, color 0.5s ease;
    transition: text-indent 0.5s ease, color 0.5s ease;
    display: block;
    width: 200px;
  }
  & :hover {
    text-indent: 4rem;
    & a {
      color: $secondary-color;
    }
  }
  & span {
    font-size: 1.3rem;
  }
`;

 const MainNav = (props) => {
    return (
      <MainNavDiv>
        <Ul>
          <Li className={props.linkIndentHome}><a href="#" onClick={props.homeContent}>HOME</a></Li>
          <Li className={props.linkIndentSonata}><a href="#" onClick={props.sonataContent}>SONATAS <span>(adults)</span></a></Li>
          <Li className={props.linkIndentIntermezzo}><a href="#" onClick={props.intermezzoContent}>INTERMEZZI <span>(adults)</span></a></Li>
          <Li className={props.linkIndentSonatina}><a href="#" onClick={props.sonatinaContent}>SONATINA <span>(Children)</span></a></Li>
          <Li className={props.linkIndentDatesFees}><a href="#" onClick={props.datesFeesContent}>DATES & FEES</a></Li>
          <Li className={props.linkIndentLive}><a href="#" onClick={props.liveContent}>LIVE! & CHAT</a></Li>
          <Li className={props.linkIndentVideoArchive}><a href="#" onClick={props.videoArchiveContent}>VIDEO ARCHIVE</a></Li>
          <Li className={props.linkIndentGeneral}><a href="#" onClick={props.generalContent}>GENERAL</a></Li>
          <Li className={props.linkIndentMisc}><a href="#" onClick={props.miscContent}>MISC</a></Li>
        </Ul>
      </MainNavDiv>
    )
 };

export default MainNav;
Run Code Online (Sandbox Code Playgroud)

每个Li组件都从附有类的父级导入道具。例如,第一个列表项将在单击时缩进该列表项,并取消所有其他列表项的缩进。这全部保持在父状态。到目前为止一切都很好。现在,这个缩进的类是在scss文件中定义的:

.main-nav__indented {
  border-bottom: 1px dotted $secondary-color !important;
  & a {
    text-indent: 5rem;
    color: $secondary-color !important;
  }
}
Run Code Online (Sandbox Code Playgroud)

我不想保留那个缩进类的scss文件。应该在MainNavDiv组件中的某个位置定义它,以便我可以将scss文件从项目中删除。但是我对如何实现它感到困惑。

我可以以某种方式使用“ attrs”方法吗?

const MainNavDiv = styled.div.attrs({
  className = // something here
})`
  display: none...
  ...
`;
Run Code Online (Sandbox Code Playgroud)

除了在scss文件中之外,如何在哪里定义main-nav__indented类?

joh*_*ter 5

您可以删除className道具并添加道具isIndented={props.linkIndentHome}props.linkIndentHome是持有true或false的布尔值,表示是否缩进。

将道具传递到Li组件,并在此处使用该组件进行决策。如下所示:

const Li = styled.li`
  border-bottom: 1px dotted #D3D3D3;
  text-indent: 3rem;
  ...other styles
  ${props => props.isIndented && `
    border-bottom: 1px dotted
    ...whatever other styles for indentation
`}
`
Run Code Online (Sandbox Code Playgroud)