【问题标题】:Styled-components React HTML elements factory for React Components用于 React 组件的样式化组件 React HTML 元素工厂
【发布时间】:2021-08-19 22:21:42
【问题描述】:

我有一个非常基本的组件,它显示页面标题(<h1> 标签)和子标题(<h3> 标签),所以如果我想更新任何样式或添加特定功能,我可以在一个地方更新它。

有了这个,我正在开发一个样式组件,但我无法让它工作。我查看了here,这是一个很好的起始示例,但我希望用完整的书面示例完成它,这样我就可以看到我做错了什么。

我正在尝试将我的 select 标签放在我的标题标签旁边。我能够让它与原始/精确的 html 一起工作,但是当我尝试将它实现到一个组件中时,我似乎无法让它工作。对我做错了什么有任何想法吗? 这是我的代码:

PageHeaderSubSection.js

import React from 'react'
export default class PageHeaderSubSection extends React.Component {
  render() {
    return (
      <h3 className="header-sub-content header-sub-name">
        {this.props.children}
      </h3>
    )
  }
}

MainPage.js

import React from 'react'
import styled from 'styled-components'
import PageHeader from '../common/page/PageHeader'
import PageHeaderSubSection from '../common/page/PageHeaderSubSection'


const StyledPageHeaderSubSection = styled(PageHeaderSubSection)``

const FormHeaderWithButtonStyle = styled.div`
  ${StyledPageHeaderSubSection} {
    margin: 0;
    display: inline-block;
  }
  select {
  vertical-align: text-bottom;
  }
`

class MainPage extends React.Component {

  render() {
    return (
      <>
        <PageHeader>Main</PageHeader>
        <FormHeaderWithButtonStyle>
          <PageHeaderSubSection>Main Modifiable Data</PageHeaderSubSection>
          <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
          <select className="form-control w-auto" >
            <option key={0} value={0}>None</option>
            <option key={1} value={"Select 1"}>{"Select 1"}</option>
            <option key={2} value={"Select 2"}>{"Select 2"}</option>
            <option key={3} value={"Select 3"}>{"Select 3"}</option>
          </select>
        </FormHeaderWithButtonStyle>
        <MoreDataHere />
      </>
    )
  }
}

【问题讨论】:

  • 为什么要在标题标签旁边添加select
  • h3 默认是块元素。尝试在 h3 元素的 css 选择器中设置 display: inlinestackoverflow.com/questions/26166907/text-inline-after-h3/…
  • @YahyaParvar 我很困惑,我如何同时使用 CSS 和样式组件?你会建议我做什么?
  • @rexessilfie 我只想在同一“行”中进行选择。当我只使用h3 时,我已经让display: inline 工作了。但是,我正在尝试找出样式组件以使用问题中的链接中提到的组件。
  • 在查看了您问题中链接的示例后,我想我更清楚您的意思了!可能的答案即将出现。

标签: reactjs styled-components


【解决方案1】:

如果您的组件FormHeaderWithButtonStylePageHeaderSubsection 的子组件,则您要做的是根据上下文设置其样式。

styled-components 文档中有一个示例 here

styled-components 示例中抽象出来,这是您想要的设置:

const Parent = styled.div``;

const Child = styled.h3`
  ${Parent} & {
    display: inline-block;
  }
`;

function MyComponent() {
  return (
    <Parent>
      <Child>Hello</Child>
      <span>world</span>
    </Parent>
  );
}

注意事项

为此,父组件和子组件都必须是styled-components

  • 如果您要根据上下文设置样式的组件是基本的 React 组件,请将其扩展为样式化组件,就像 here 所做的那样。

示例

应用于你的具体例子,你会想要这样的东西:

// Stubs to replace your imports.
const PageHeader = ({ children }) => <h2>{children}</h2>;
const PageHeaderSubSection = ({ className, children }) => (
  <h3 className={className}>{children}</h3>
); // OR const PageHeaderSubSection = styled.h3``

// Changes start here
const FormHeaderWithButtonStyle = styled.div`
  select {
    vertical-align: text-bottom;
  }
`;

// Extend PageHeaderSubSection and apply a contextual style.
// '${FormHeaderWithButtonStyle} &' will target StyledPageHeaderSubSection that are preceeded by (have a parent of) FormHeaderWithButtonStyle.
// The '&' represents the css class for the current component.
const StyledPageHeaderSubSection = styled(PageHeaderSubSection)`
  ${FormHeaderWithButtonStyle} & {
    margin: 0;
    display: inline-block;
  }
`;

class MainPage extends React.Component {
  render() {
    return (
      <>
        <PageHeader>Main</PageHeader>
        <FormHeaderWithButtonStyle>
          {/** Make sure to use StyledPageHeaderSubSection here so that the contextual style can be applied. */}
          <StyledPageHeaderSubSection>
            Main Modifiable Data
          </StyledPageHeaderSubSection>
          <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
          <select className="form-control w-auto">
            <option key={0} value={0}>
              None
            </option>
            <option key={1} value={"Select 1"}>
              {"Select 1"}
            </option>
            <option key={2} value={"Select 2"}>
              {"Select 2"}
            </option>
            <option key={3} value={"Select 3"}>
              {"Select 3"}
            </option>
          </select>
        </FormHeaderWithButtonStyle>
      </>
    );
  }
}

Link to CodeSandbox.

参考资料:

【讨论】:

  • 终于有时间看看这个了。我不确定这是否是我要找的。我的PageHeaderSubSection 不是styled-component 的组件。这是一个返回&lt;h3&gt; 标签的类。如果我的组件是styled-component,您的示例可能会起作用,但这不是我所拥有的。我错过了什么吗?
  • 实际上可以使用className 属性将非styled-component 扩展为styled-component,如here 所示。这样做应该可以让你扩展得很好。我将更新我的答案以使用 PageHeaderSubsection 作为常规反应组件。
  • 这绝对是正确的答案!但我遇到了一个问题。您的代码有效(显然,感谢 CodeSandbox),但您使用 const 来代替我的导入。当我将 PageHeaderSubSection 组件导入您的代码时(就像我的问题一样),样式不起作用。知道为什么吗?如果您取出 const PageHeaderSubSection... 并将其替换为类的导入(组件与我的问题中的 PageHeaderSubSection 完全相同),您会看到样式不适用于 h3。你知道为什么这适用于 const 而不是类导入吗?
  • 我认为这应该为您提供方便:codesandbox.io/s/…
  • 哦,等等,这是因为我不允许允许将类添加到 PageheaderSubSection 组件中,就像您允许将类添加到 className 一样?
【解决方案2】:

如果您想要一个可以在一个地方重复使用和更改的 h3 组件,为什么不创建一个样式化的组件。您可以创建一个样式化组件页面并包含所有样式化组件,以便您可以将它们导入任何页面。

styled.styles.js

export const styledSubHeader= styled.h3`
margin: 0 ;
display: inline-block;

` 

然后将它导入你想要使用的页面并将你的内容包装在标签中?

<styledSubHeader> SubHeaderContent </styledSubHeader>

或者在你的 Main.js 中使用它

import React from 'react'
import styled from 'styled-components'
import PageHeader from '../common/page/PageHeader'
import PageHeaderSubSection from '../common/page/PageHeaderSubSection'




const FormHeaderWithButtonStyle = styled.div`
  
`
const styledSubHeader = styled.h3`
margin: 0 ;
display: inline-block;

` 

class MainPage extends React.Component {

  render() {
    return (
      <>
        <PageHeader>Main</PageHeader>
        <FormHeaderWithButtonStyle>
          <styledSubHeader>Main Modifiable Data</styledSubHeader>
          <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
          <select className="form-control w-auto" >
            <option key={0} value={0}>None</option>
            <option key={1} value={"Select 1"}>{"Select 1"}</option>
            <option key={2} value={"Select 2"}>{"Select 2"}</option>
            <option key={3} value={"Select 3"}>{"Select 3"}</option>
          </select>
        </FormHeaderWithButtonStyle>
        <MoreDataHere />
      </>
    )
  }

【讨论】:

  • 在设计意义上,将我的styled-component 包含到我的 PageHeaderSubSection 组件中更有意义。我不能这样做,因为我不希望我的所有 h3 标签都是 inline-blocks。
猜你喜欢
  • 2020-09-26
  • 1970-01-01
  • 2019-12-16
  • 1970-01-01
  • 2021-05-01
  • 2020-12-05
  • 2019-10-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多