简体   繁体   English

React Styled组件:如何基于道具添加CSS样式?

[英]React Styled component: how to add css styles based on props?

I've been trying to find the solution to my problem. 我一直在寻找解决我问题的方法。 I have several Heading Tags (H1, H2 etc) each in their own file. 我在自己的文件中有几个标题标签(H1,H2等)。 I would like to add some css when calling them based on a prop. 我想在基于prop调用它们时添加一些CSS。 Some headings have a small border-bottom and some don't. 有些标题底端有一个小边框,有些则没有。 So, in order to refractor my code, I want to add some css based on a prop. 因此,为了修改我的代码,我想添加一个基于prop的CSS。 I can't seem to find a way. 我似乎找不到办法。

Here's an example of Heading H2: 这是标题H2的示例:

import styled from 'styled-components';
import colors from '../../../../colors'; 
import fonts from '../../../../fonts';
import fontWeights from '../../../../fontWeights';

const HeadingH2 = styled.h2`
  color: ${colors.text};
  font-family: ${fonts.montSerrat};
  font-size: 1.6em;
  font-weight: ${fontWeights.light};
  letter-spacing: 0.2em;
  padding-bottom: 0.7em;
  position: relative;
  text-transform: uppercase;
  text-align: center;
  &:after{
    content: "";
    display: block;
    height: 3px;
    width: 45px;
    background-color: currentColor;
    /* position */
    position: absolute;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
  }
`;

export default HeadingH2

Example of calling Heading H2: 调用标题H2的示例:

import React from 'react';
import HeadingH2 from '../../common/headings/heading_h2';
import HeadingBaseline from '../../common/headings_baseline';


// Features
import {SectionContainer, FeaturesContainer} from './features.style';

import Feature from './feature';
import feature1 from '../../../img/features/feature1.png';
import feature2 from '../../../img/features/feature2.png';
import feature3 from '../../../img/features/feature3.png';

// Text
import Text from '../../../content';

const Features = () => {
  return(
    <SectionContainer id={"what"}>
      <HeadingH2>
        What We Do
      </HeadingH2>
    <HeadingBaseline>
      {Text.headingBaseline}
    </HeadingBaseline>
  <FeaturesContainer>
    <Feature 
      src={feature1} 
      headingText={Text.feature1.heading}
      paragraph={Text.feature1.paragraph}
      />
    <Feature 
      src={feature2} 
      headingText={Text.feature2.heading}
      paragraph={Text.feature2.paragraph}
      />
    <Feature 
      src={feature3} 
      headingText={Text.feature3.heading}
      paragraph={Text.feature3.paragraph}
      />
  </FeaturesContainer>
</SectionContainer>
)
};

export default Features;

I want to extract the following CSS properties 我想提取以下CSS属性

position: relative;
text-transform: uppercase;
text-align: center;
&:after{
 content: "";
 display: block;
 height: 3px;
 width: 45px;
 background-color: currentColor;
 /* position */
 position: absolute;
 bottom: 0;
 left: 50%;
 transform: translateX(-50%);

So, assuming I have the above CSS rule in a separate file, how do I add/import them using props on my styled component HeadingH2. 因此,假设我在单独的文件中具有上述CSS规则,如何在样式化的组件HeadingH2上使用道具添加/导入它们。

Thanks for the help :) 谢谢您的帮助 :)

Something like this works: 像这样的作品:

const HeadingH2 = styled.h2`
  position: ${props => props.relative && 'relative'};
  padding: ${props => props.paddingBottom ? '0 0 20px 0' : '0'};
}
`;

Then use like this: 然后像这样使用:

<HeadingH2 relative paddingBottom />

Possible answer: 可能的答案:

I add the following CSS rules in a separate file like so. 我将以下CSS规则添加到一个单独的文件中,如下所示。 I create a function which returns a string of text. 我创建了一个返回字符串的函数。 I can import this function and add those rules to any component I wish. 我可以导入此函数,并将这些规则添加到我希望的任何组件中。

export const borderBottom = () => {
  return `
   position: relative;
   text-transform: uppercase;
   text-align: center;
   &:after{
    content: "";
    display: block;
    height: 3px;
    width: 45px;
    background-color: currentColor;
    /* position */
    position: absolute;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
  } 
`
 }

And use it like so on any heading or component that I wish: 并在希望的任何标题或组件上像这样使用它:

import styled from 'styled-components';
import colors from '../../../../colors';
import fonts from '../../../../fonts';
import fontWeights from  '../../../../fontWeights';
import {borderBottom} from '../../../../css';

const HeadingH5 = styled.h5`
  color: ${colors.black};
  font-family: ${fonts.montSerrat};
  font-size: 1em;
  font-weight: ${fontWeights.light};
  letter-spacing: 0.1em;
  padding-bottom: 0.45em;
  margin-bottom: 25px;
  ${borderBottom}
`  
;

export default HeadingH5;

This works for me. 这对我有用。 Any other suggestions are welcome. 欢迎其他任何建议。

You can also use css helper from styled-components to create a SharedStyles.js file. 您还可以使用styled-components css帮助器来创建SharedStyles.js文件。

In the demo you can see it in action. 演示中,您可以看到它的运行情况。 Just using it in a style of an inherited component is not working as expected. 仅以继承的组件样式使用它无法正常工作。 If I'm adding it to StyledBase then the variables are not correctly added afterwards (hover style override stops working). 如果我将其添加到StyledBase则此后变量未正确添加(悬停样式覆盖会停止工作)。 That's why I copied ${borderBottom} to each styled component Heading1 / Heading2 instead of adding it to StyledBase . 这就是为什么我将${borderBottom}复制到每个样式化的组件Heading1 / Heading2而不是将其添加到StyledBase

I think having a level prop for the heading is a good idea but I would handle it differently by creating a HeadingBase component and add your styles to a StyledBase component (also see code in the demo). 我认为为标题准备一个水平道具是个好主意,但我会通过创建HeadingBase组件并将样式添加到StyledBase组件中来进行StyledBase (另请参见演示中的代码)。

The HeadingBase code looks like this: HeadingBase代码如下所示:

const HeadingBase = ({ className, children, level = 1 }) =>
    React.createElement(`h${level}`, { className }, children);

It's a component that renders h1,h2,... tags based on the prop level passed (defaults to h1). 它是根据传递的prop level渲染h1,h2,...标签的组件(默认为h1)。 The h-tag receives className as props (needed for styled-components) and contains the children passed to the component. h标签将className作为prop接收(样式化组件需要),并包含传递给该组件的子代。

SharedStyles.js SharedStyles.js

import { css } from "styled-components";

export const borderBottom = css`
    &:after{
        content: "";
        display: block;
        height: 3px;
        width: 200px;
        background-color: ${props => props.color || "black"};
        /* position */
        position: absolute;
        bottom: 0;
        left: 50%;
        transform: translateX(-50%);
`;

Then you can import it with import { borderBottom } from "./SharedStyles"; 然后,您可以使用import { borderBottom } from "./SharedStyles";导入它import { borderBottom } from "./SharedStyles"; and add it to your styled-component like following: 并将其添加到样式化组件中,如下所示:

const Heading1= styled.h1`
    ${borderBottom}
`;

Why not just have a headingLevel prop? 为什么不只拥有headingLevel道具? and then pass it into the styled component? 然后将其传递给样式化组件? And just have one StyledHeader styled component as I'm guessing the code is the mostly the same in all the heading styles files? 而且只有一个StyledHeader样式的组件,因为我猜代码在所有标题样式文件中都基本相同? Which is a big no no, you want to always try not to repeat your code. 很大,不,您要始终尝试不重复代码。

const Features = () => {
  return(
    <SectionContainer id={"what"}>
      <StyledHeader
        headingLevel={headingLevel}
      >
        What We Do
      </StyledHeader>
    <HeadingBaseline>
      {Text.headingBaseline}
    </HeadingBaseline>
  <FeaturesContainer>
    <Feature 
      src={feature1} 
      headingText={Text.feature1.heading}
      paragraph={Text.feature1.paragraph}
      />
    <Feature 
      src={feature2} 
      headingText={Text.feature2.heading}
      paragraph={Text.feature2.paragraph}
      />
    <Feature 
      src={feature3} 
      headingText={Text.feature3.heading}
      paragraph={Text.feature3.paragraph}
      />
  </FeaturesContainer>
</SectionContainer>
)
};

export default Features;

And in your StyledHeader file 并在您的StyledHeader文件中

The below function will take your passed in heading level of h1 , h2 , h3 and will apply a border, if not the above 3 heading level it will be 0 value. 下面的函数将采用您传入的标题级别h1h2h3并应用边框,如果不是上面的3个标题级别,它将为0值。 I'd do some checks to ensure the value is lower case eg toLowerCase() 我会做一些检查以确保该值是小写的,例如toLowerCase()

const getBorder = ({ headingLevel } ) => {
  const headingLevelMap = {
    h1: 0.7,
    h2: 0.6,
    h3: 0.6,
  };

  return headingLevelMap[headingLevel] || 0;
}

const HeadingH2 = styled.headingLevel`
  color: ${colors.text};
  font-family: ${fonts.montSerrat};
  font-size: 1.6em;
  font-weight: ${fontWeights.light};
  letter-spacing: 0.2em;
  padding-bottom: 0.7em;
  border-bottom: ${getCorrectBorderBottom}em solid black
  position: relative;
  text-transform: uppercase;
  text-align: center;
  &:after{
    content: "";
    display: block;
    height: 3px;
    width: 45px;
    background-color: currentColor;
    /* position */
    position: absolute;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
  }
`;

I'd also check that if the value of the passed in headingLevel is not any of the 6 heading levels it should have a default value of whatever you want. 我还要检查,如果传入的headingLevel值不是6个标题级别中的任何一个,它的默认值应该是您想要的任何值。

The above was just quick pseudo code, but hopefully get the general idea here? 上面只是快速的伪代码,但希望能在这里得到一般的想法? Let me know it comments if not. 如果没有,请通知我。

I'd also recommend that you split your Title component out into a separate component. 我还建议您将“ Title组件拆分为单独的组件。

You should definely check this: typestyle 您应该明确地检查以下内容: typestyle

the best way you can write dynamic css (for me). 您可以编写动态CSS的最佳方法(对我来说)。 Works perfectly with react, even with ssr if you need it... 与react完美搭配,即使您需要也可以与ssr一起使用...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 React - 如何使用样式组件向组件添加新样式 - React - How to add new styles to a component using styled-component 如何在 react 和 next js 中使用 Styled 组件创建全局 styles,使用 css 文件和 styled 组件的组合是否更好? - How to Create global styles with Styled components in react and next js and is it better to use combination of css files and styled component? 如何在 styles 的反应中添加道具? - How to add props in react for styles? 根据传递给组件的道具分配样式组件的CSS属性 - Assign styled-component CSS property based on props passed to component 在React Native中为样式化组件自定义组件添加样式 - Add styles to Styled Component custom Component in React Native 如何在样式组件中键入属性和样式道具 - React - How to type attrs and styles props in styled components - React 如何使用样式化 MUI 基于道具制作不同的组件变体? - How to make different variants of component based on props using styled MUI? 在 React Native 中将 props 的样式添加到现有组件 styles - Add style from props to existing component styles in React Native 如何通过带有样式组件的道具传递 styles 而无需在组件内创建组件 - How to pass styles via props with styled components without having to create the component inside the component 如何将 redux 道具传递给 React typescript 中的样式化组件 - How to pass redux props to styled component in react typescript
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM