web-dev-qa-db-ja.com

基になるDOM要素に小道具を渡さずにスタイル付きコンポーネントを拡張する方法は?

サードパーティコンポーネントを拡張するスタイル付きコンポーネントがあります。

import Resizable from 're-resizable';
...
const ResizableSC = styled(Resizable)``;
export const StyledPaneContainer = ResizableSC.extend`
    flex: 0 0 ${(props) => props.someProp}px;
`;


const PaneContainer = ({ children, someProp }) => (
    <StyledPaneContainer
        someProp={someProp}
    >
        {children}
    </StyledPaneContainer>
);

export default PaneContainer;

これにより、ブラウザコンソールで次のエラーが発生しました。

警告:ReactはDOM要素のsomePropプロップを認識しません。意図的にDOMにカスタム属性として表示したい場合は、小文字someProp代わりに、誤って親コンポーネントから渡した場合は、DOM要素から削除してください。

だから、私はプロップをdata-* 属性名:

import Resizable from 're-resizable';
...
const ResizableSC = styled(Resizable)``;
export const StyledPaneContainer = ResizableSC.extend`
    flex: 0 0 ${(props) => props['data-s']}px;
`;


const PaneContainer = ({ children, someProp }) => (
    <StyledPaneContainer
        data-s={someProp}
    >
        {children}
    </StyledPaneContainer>
);

export default PaneContainer;

これは機能しますが、DOM要素に渡されずにスタイル付きコンポーネントでプロップを使用するネイティブの方法があるかどうか疑問に思いました(?)

19
JoeTidee

vdanchenkov on this styled-components github issue で提案されているように、プロップを分解して関連するもののみをResizableに渡すことができます

const ResizableSC = styled(({ someProp, ...rest }) => <Resizable {...rest} />)`
    flex: 0 0 ${(props) => props.someProp}px;
`;
25
tskjetne

SCとreact-router's Linkの問題のためにここに上陸した(私のような)人々のために。

これは基本的に@tskjetneと同じ答えですが、JS構文スタイルです。

const StyledLink = styled(({ isCurrent, ...rest }) => <Link {...rest} />)(
  ({ isCurrent }) => ({
    borderBottomColor: isCurrent ? 'green' : 'transparent',
  }),
)
7
Fellow Stranger

defaultPropsで試すことができます:

import Resizable from 're-resizable';
import PropTypes from 'prop-types';
...
const ResizableSC = styled(Resizable)``;
export const StyledPaneContainer = ResizableSC.extend`
    flex: 0 0 ${(props) => props.someProp}px;
`;

StyledPaneContainer.defaultProps = { someProp: 1 }

const PaneContainer = ({ children }) => (
    <StyledPaneContainer>
        {children}
    </StyledPaneContainer>
);

export default PaneContainer;

'attrs'を使用して小道具を渡すこともできます。これは、追加の小道具を添付するのに役立ちます(スタイル付きコンポーネントの公式ドキュメントからの例):

const Input = styled.input.attrs({
  // we can define static props
  type: 'password',

  // or we can define dynamic ones
  margin: props => props.size || '1em',
  padding: props => props.size || '1em'
})`
  color: palevioletred;
  font-size: 1em;
  border: 2px solid palevioletred;
  border-radius: 3px;

  /* here we use the dynamically computed props */
  margin: ${props => props.margin};
  padding: ${props => props.padding};
`;

render(
  <div>
    <Input placeholder="A small text input" size="1em" />
    <br />
    <Input placeholder="A bigger text input" size="2em" />
  </div>
); 
0
Chasing Unicorn