简体   繁体   English

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

[英]styled-component .attrs - React does not recognize prop

I am trying to pass down a prop into my styled component.我正在尝试将道具传递到我的样式组件中。 It works as expected, but React throws the known 'Unknown Prop' error.它按预期工作,但 React 抛出了已知的“Unknown Prop”错误。

I tried to use the spread operator at numerous places but neither did work.我试图在很多地方使用传播运算符,但都没有奏效。

The styled component I want to pass down the prop to:我想将道具传递给的样式组件:

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

The parent component:父组件:

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

And how I use it on the page:以及我如何在页面上使用它:

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

I expect it to work, which does, but not without the following error:我希望它可以工作,确实可以,但并非没有以下错误:

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)

Update: Use transient props更新:使用瞬态道具

With the release 5.1.0 you can use transient props .5.1.0 版本中,您可以使用transient props This way you do not need an extra wrapper ie unnecessary code is reduced:这样您就不需要额外的包装器,即减少了不必要的代码:

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.瞬态 props 是一种新模式,用于传递仅由样式组件显式使用的 props,而不打算向下传递到更深的组件层。 Here's how you use them:以下是您如何使用它们:

const Comp = styled.div`
  color: ${props => props.$fg || 'black'};
`;

render(<Comp $fg="red">I'm red!</Comp>);

Note the dollar sign ($) prefix on the prop;注意道具上的美元符号 ($) 前缀; this marks it as transient and styled-components knows not to add it to the rendered DOM element or pass it further down the component hierarchy.这将其标记为瞬态和样式组件知道不将其添加到呈现的 DOM 元素或将其进一步向下传递到组件层次结构。

The new answer should be:新的答案应该是:

Component:成分:

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

Declaration of styled component:样式组件的声明:

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

To prevent components that pass all props to a DOM element, create a wrap of your component but do not pass your custom props to the children component via "Object destructuring".为了防止组件将所有 props 传递给 DOM 元素,请创建一个组件的包装,但不要通过“对象解构”将自定义 props 传递给子组件。 In this way, you can style the wrapped component and styled-components can access to the prop but the children will not have custom properties, and your warning will disappear.通过这种方式,您可以为包装的组件设置样式,并且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;

You can learn more about deestructuring at Mozilla docs.您可以在Mozilla文档中了解有关解构的更多信息。

The correct syntax should be:正确的语法应该是:

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

Edit: Actually, if you just want to have a default style, why don't you have it in the styles directly:编辑:实际上,如果您只想拥有默认样式,为什么不直接在样式中使用它:

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

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM