styled-component .attrs - React 无法识别 prop

styled-component .attrs - React does not recognize prop

我正在尝试将道具传递到我的样式化组件中。它按预期工作,但 React 抛出已知的 'Unknown 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)

正确的语法应该是:

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

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

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

为了防止组件将所有道具传递给 DOM 元素,请创建组件包装,但不要通过 "Object destructuring" 将自定义道具传递给 children 组件。通过这种方式,您可以设置包装组件的样式,并且 styled-components 可以访问道具,但 children 将没有自定义属性,并且您的警告将消失。

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 文档中了解更多关于解构的信息。

更新:使用瞬态道具

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

Transient props are a new pattern to pass props that are explicitly consumed only by styled components and are not meant to be passed down to deeper component layers. Here's how you use them:

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
  /* ...  */
`;