【问题标题】:How to style all child components from parent component via styled component如何通过样式化组件为父组件中的所有子组件设置样式
【发布时间】:2020-04-17 14:24:49
【问题描述】:

我一直在努力通过 styled-components 为父组件设置子组件的样式 下面是代码。 我已经评论了我正在苦苦挣扎的地方以及我想要实现的目标。styled-components 文档没有帮助。

代码沙盒链接: https://codesandbox.io/s/adoring-pare-exjjt?file=/src/App.js

    import React from 'react';
    import { render } from "react-dom";
    import styled from 'styled-components'
    import { Button, Grid ,Container} from 'semantic-ui-react'
    import PropTypes from 'prop-types'

    const mID = 'test'

    const StyledBlock = styled(Container)`
    {/*i don't want to style here */}

      /* height: 450px;
      background-color: #f7f7f7;
      @media only screen and (max-width: 767px) and (min-width: 320px) {
        height: 550px;
      } */
    `
    const StyledSection = styled.section`
      background: #ffffff;
      box-shadow: 0px 1px 0px #dfdfdf;
      margin: 12% 10% 10% 30%;
      height: 150px;
      width: 170px;
      @media only screen and (max-width: 767px) and (min-width: 320px) {
        margin: 10% 0 25% 25%;
        width: 172px;
      }
    `
    const Header = styled.h4`
      text-align: center;
      position: relative;
      top: 10%;
    `
    const StyledButton = styled(Button)`
      position: relative;
      bottom: -60px;
      margin: 0px;
      width: 100%;
      top: 9.32%;
    `

    const Report = (name) => {
      const handleClick = async (e) => {
        console.log(e)
      }

      return (
        <Grid.Column key={name} className={`${mID}_preview`}>
          <StyledSection>
            <Header>{name}</Header>
            <StyledButton secondary onClick={() => handleClick(name)} >
              Download
            </StyledButton>
          </StyledSection>
        </Grid.Column>
      )
    }

    const Reports = () => {
    return(
      <Container>
        <StyledBlock>
          <Grid>
            <Grid.Row>{["deen","john"].map((name) => Report(name))}</Grid.Row>
          </Grid>
        </StyledBlock>
      </Container>
    )}

    Reports.propTypes = {
      names: PropTypes.array,
      onlineShowId: PropTypes.number
    }

//below code is not able to pass css. don't see these css anywhere applied . why ?
    const StyledReports = styled(Reports)`
    background-color: yellow
     .${mID} {
        &_preview {
          color: red
        }
     }

     ${StyledBlock}{
      background-color: red
     }
    `

    render(<StyledReports />, document.getElementById("root"))

【问题讨论】:

  • style-components 的整体思想是尽可能地保持样式接近,为什么要在父组件中保留样式?
  • 这不是样式化组件的全部想法。就是封装css。即使你在parent中做,它仍然是从要使用这个组件的组件中封装出来的
  • 在我的项目中,我们就是这样做的。我们在父组件中设置样式而不是在按钮等组件的子部分中设置样式。我想学习如何这样做
  • 你能在代码沙箱中创建一个最小的工作示例吗?
  • @rzwnahmd 添加

标签: reactjs styled-components


【解决方案1】:

我想出了解决办法

你需要像这样在父组件上有className

import React from 'react';
import { render } from "react-dom";
import styled from 'styled-components'
import { Button, Grid ,Container} from 'semantic-ui-react'
import PropTypes from 'prop-types'

const mID = 'test'

const StyledBlock = styled(Container)`
{/*i don't want to style here */}
  background-color: yellow ;
  height: 450px;
  @media only screen and (max-width: 767px) and (min-width: 320px) {
    height: 550px;
  }
  > * { //applies for all under parent class ,class that is applied by SC on parent
    color: magenta
  }
  & .${mID}__column{ //all elements under & i.e parent class (which is StyledBlock) with class {mID}__column
    color :green;
  }
`
const StyledSection = styled.section`
  background: #ffffff;
  box-shadow: 0px 1px 0px #dfdfdf;
  margin: 12% 10% 10% 30%;
  height: 150px;
  width: 170px;
  @media only screen and (max-width: 767px) and (min-width: 320px) {
    margin: 10% 0 25% 25%;
    width: 172px;
  }
`
const Header = styled.h4`
  text-align: center;
  position: relative;
  top: 10%;
`
const StyledButton = styled(Button)`
  position: relative;
  bottom: -60px;
  margin: 0px;
  width: 100%;
  top: 9.32%;
`

const Report = (name) => {
  const handleClick = async (e) => {
    console.log(e)
  }

  return (
    <Grid.Column key={name} className={`${mID}__column`}>
      <StyledSection>
        <Header>{name}</Header>
        <StyledButton secondary onClick={() => handleClick(name)} >
          Download
        </StyledButton>
      </StyledSection>
    </Grid.Column>
  )
}

const Reports = ({className}) => {
  console.log('className ',className)
return(
  <Container className={className}>
    <StyledBlock>
      <Grid>
        <Grid.Row>{["deen","john"].map((name) => Report(name))}</Grid.Row>
      </Grid>
    </StyledBlock>
  </Container>
)}

Reports.propTypes = {
  names: PropTypes.array,
  onlineShowId: PropTypes.number
}

const StyledReports = styled(Reports)`
   background-color:blue; //to apply this,SC need a className on this element to apply
 .${mID} {
    &__column {
      color: gold
    }
 }

 ${StyledBlock}{
  background-color: red  ; //higher specificity than in styledblock
 }
`

render(<StyledReports />, document.getElementById("root"))

【讨论】:

    猜你喜欢
    • 2021-09-27
    • 2023-03-26
    • 2021-09-20
    • 1970-01-01
    • 2016-07-31
    • 1970-01-01
    • 1970-01-01
    • 2021-09-19
    相关资源
    最近更新 更多