【问题标题】:styled-component .attrs - React does not recognize propstyled-component .attrs - React 无法识别道具
【发布时间】:2019-12-26 10:32:23
【问题描述】:

我正在尝试将一个道具传递给我的样式组件。它按预期工作,但 React 会抛出已知的“Unknown Prop”错误。

我尝试在很多地方使用扩展运算符,但都没有奏效。

我想将 prop 传递给的样式化组件:

const StyledBackgroundImage = styled(BackgroundImage).attrs(({minHeight}) => ({
  minHeight: minHeight || "60vh",
}))`
  min-height: ${({minHeight}) => minHeight};
  /* ...  */
`;

父组件:

const ImageWithText = ({imageData, minHeight, children}) => {
  return (
    <StyledBackgroundImage 
    Tag="div"
    backgroundColor={'#000000'}
    fluid={imageData}
    minHeight={minHeight}
    >
        {children}
    </StyledBackgroundImage>
  )
}

以及我如何在页面上使用它:

<ImageWithText imageData={data.headerBackgroundImage.childImageSharp.fluid} minHeight='50vh'>

我希望它可以工作,但并非没有以下错误:

Warning: React does not recognize the `minHeight` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `minheight` instead. If you accidentally passed it from a parent component, remove it from the DOM element.
    in div (created by BackgroundImage)
    in BackgroundImage (created by Context.Consumer)
    in StyledComponent (created by ImageWithText__StyledBackgroundImage)
    in ImageWithText__StyledBackgroundImage (at ImageWithText.js:32)
    in ImageWithText (at pages/index.js:20)
    in section (created by Context.Consumer)
    in StyledComponent (created by LayoutComponents__Section)
    in LayoutComponents__Section (at pages/index.js:19)
    in main (at layout.js:10)
    in Layout (at pages/index.js:17)
    in IndexPage (created by HotExportedIndexPage)
    in AppContainer (created by HotExportedIndexPage)
    in HotExportedIndexPage (created by PageRenderer)
    in PageRenderer (at json-store.js:93)
    in JSONStore (at root.js:51)
    in RouteHandler (at root.js:73)
    in div (created by FocusHandlerImpl)
    in FocusHandlerImpl (created by Context.Consumer)
    in FocusHandler (created by RouterImpl)
    in RouterImpl (created by Context.Consumer)
    in Location (created by Context.Consumer)
    in Router (created by EnsureResources)
    in ScrollContext (at root.js:64)
    in RouteUpdates (at root.js:63)
    in EnsureResources (at root.js:61)
    in LocationHandler (at root.js:119)
    in LocationProvider (created by Context.Consumer)
    in Location (at root.js:118)
    in Root (at root.js:127)
    in _default (at app.js:65)

【问题讨论】:

    标签: javascript reactjs styled-components


    【解决方案1】:

    更新:使用瞬态道具

    使用release 5.1.0,您可以使用transient props。这样您就不需要额外的包装器,即减少不必要的代码:

    瞬态 props 是一种新模式,用于传递仅由样式化组件显式使用的 props,并不意味着向下传递到更深的组件层。以下是您如何使用它们:

    const Comp = styled.div`
      color: ${props => props.$fg || 'black'};
    `;
    
    render(<Comp $fg="red">I'm red!</Comp>);
    

    注意道具上的美元符号($)前缀;这将其标记为瞬态,并且样式组件知道不将其添加到渲染的 DOM 元素或将其进一步传递到组件层次结构中。

    新的答案应该是:

    组件:

    <ImageWithText 
      $imageData={data.headerBackgroundImage.childImageSharp.fluid} // notice the '$'
      minHeight='50vh'>
    

    样式化组件的声明:

    const StyledBackgroundImage = styled(BackgroundImage).attrs(({$minHeight}) => ({
      minHeight: minHeight || "60vh",
    }))`
      min-height: ${({$minHeight}) => $minHeight}; // notice the '$' before the prop name
      /* ...  */
    `;
    

    【讨论】:

      【解决方案2】:

      为防止组件将所有道具传递给 DOM 元素,请创建组件的包装,但不要通过“对象解构”将自定义道具传递给子组件。这样,您可以设置包装组件的样式,styled-components 可以访问该道具,但子项将没有自定义属性,并且您的警告将消失。

      import React from 'react';
      import styled from 'styled-components';
      import Typography from '@material-ui/core/Typography'
      
      const WrappedTypography = ({ maxWidth, ...props }) => {
        return <Typography {...props} />
      }
      
      const Text = styled(WrappedTypography) `
        ${({ maxWidth }) => maxWidth ? `max-width: ${maxWidth}` : null}
      `
      export default Text;
      

      您可以在 Mozilla docs 了解有关解构的更多信息。

      【讨论】:

        【解决方案3】:

        正确的语法应该是:

        const StyledBackgroundImage = styled(BackgroundImage).attrs({
          minHeight: props => props.minHeight || "60vh"
        })`
          min-height: ${({ minHeight }) => minHeight};
          /* ...  */
        `;
        `
        

        编辑: 其实,如果你只想有一个默认样式,为什么不直接在样式中:

        const StyledBackgroundImage = styled(BackgroundImage)`
          min-height: ${({ minHeight }) => minHeight || '60vh'};
          /* ...  */
        `;
        `
        

        【讨论】:

        • 感谢您的回答。不幸的是,这两种语法仍然抛出相同的错误。知道这里出了什么问题吗?
        • 确保我已更新到最新的样式组件版本。发生错误是因为您的某些组件将 minHeight 属性直接传递给 DOM 元素。当您像&lt;Component {...props} /&gt; 那样做某事时,通常会发生这种情况。
        • 我已经在使用当前版本(styled-components: 4.3.2, gatsby-plugin-styled-components: 3.1.2),我不使用扩展运算符,如您在我的问题中的代码。这就是为什么我想知道这是从哪里来的。有什么想法吗?
        猜你喜欢
        • 2020-11-20
        • 2019-11-18
        • 2018-09-27
        • 2021-03-31
        • 1970-01-01
        • 1970-01-01
        • 2021-05-09
        • 2018-10-20
        • 2020-02-16
        相关资源
        最近更新 更多