簡體   English   中英

如何在樣式組件v4 + TypeScript中使用prop值設置屬性?

[英]How do I set attributes using prop values in styled-components v4 + TypeScript?

摘要

鑒於:

const Link = styled.a`
  border: solid 1px black;
  border-radius: 5px;
  padding: 5px;
  margin: 10px 5px;
`;

type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement>;
const LinkAsButton = styled(Link).attrs<ButtonProps>
>(({
  as: 'button',
  className: 'btn btn-primary'
})`
  border: solid 1px red;
`;

如何將按鈕特定的道具(例如,禁用的)傳遞給LinkAsButton

回購(包括v3和v4的分支)演示了問題: https : //github.com/arteforme/v3-v4-styled-components-migration

版本3

在v3中,我可以執行以下操作:

package.json

"dependencies": {
    "@types/react": "^16.8.8",
    "@types/react-dom": "^16.8.2",
    "react": "^16.8.4",
    "react-dom": "^16.8.4",
    "react-scripts": "2.1.8",
    "styled-components": "^3.3.3",
    "typescript": "^3.3.3333"
  }

組件定義

type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement>;

const Link = styled.a`
  border: solid 1px black;
  border-radius: 5px;
  padding: 5px;
  margin: 10px 5px;
`;

const LinkAsButton = Link.withComponent('button')
  .extend.attrs<ButtonProps>({
  className: 'btn btn-primary'
})`
  border: solid 1px red;
`;

在使用代碼中,我可以在LinkAsButton組件上指定特定於按鈕的道具(例如,禁用,表單等)。

版本4

在v4中,我希望達到相同的效果; 但是,我沒有成功確定如何去做。 根據最新的資料,我已經更新LinkAsButton不再調用extendwithComponent ,而是換Link的調用styled ,並使用as指定標簽。 v4版本如下所示:

package.json

dependencies": {
    "@types/react": "^16.8.14",
    "@types/styled-components": "^4.1.14",
    "react": "^16.8.6",
    "react-dom": "^16.8.6",
    "react-scripts": "2.1.8",
    "styled-components": "^4.2.0",
    "typescript": "^3.4.5"
  }

組件定義

const LinkAsButton = styled(Link).attrs<ButtonProps>
>(({
  as: 'button',
  className: 'btn btn-primary'
})`
  border: solid 1px red;
`;

在使用代碼中,我在LinkAsButton實例上指定了disabled={true} ,但這不能編譯。 而是,出現以下錯誤:

屬性'disabled'在類型'IntrinsicAttributes&Pick,HTMLAnchorElement>,“ type” |中不存在。 “ defaultChecked” | “ defaultValue” | “ suppressContentEditableWarning” | ... 257更多... | “ referrerPolicy”>&{...; },“類型” | ... 261更多... | “ referrerPolicy”>&Partial <...>,“類型” | ....'。 TS2322

查看屬性定義

看一下定義文件,我注意到可以指定兩個通用參數。

attrs <
  U,
  NewA extends Partial<StyledComponentPropsWithRef<C> & U> & {
    [others: string]: any;
  } = {}
    > (
      attrs: Attrs<StyledComponentPropsWithRef<C> & U, NewA, T>
    ): ThemedStyledFunction<C, T, O & NewA, A | keyof NewA>;

據我所知, C是包裝的組件,我相信NewA是NewAttributes。 在這種情況下,我無法確定U是什么,但是我嘗試指定第二個通用參數。

const LinkAsButton = styled(AnchorLink).attrs<{}, ButtonProps>`
  // omitted for brevity
`

這樣做會導致以下錯誤:

類型'ButtonHTMLAttributes'不能分配給'Partial,HTMLAnchorElement>,“ type” | “ defaultChecked” | “ defaultValue” | “ suppressContentEditableWarning” | ... 257更多... | “ referrerPolicy”>&{...; }和ButtonHTMLAttributes <... >>'。 屬性“ onCopy”的類型不兼容。

掌握了這些信息后,我嘗試:

const LinkAsButton = styled(Link).attrs<
  {},
  { as: string; className: string; disabled?: boolean }
>({
  as: 'button',
  className: 'btn btn-primary'
})``;

現在我可以在標記中指定disabled ,但不能指定任何其他按鈕特定的道具(例如form

非理想的解決方案

一種方法是執行以下操作:

const LinkAsButton = styled(Link)<ButtonProps>`
  border: solid 1px red;
`;

消費代碼:

<div className="App">    
    <LinkAsButton as="button" className="btn-btn-primary" disabled={true}>
        First button
    </LinkAsButton>
    <LinkAsButton as="button" className="btn-btn-primary" disabled={true}>
        Second button
    </LinkAsButton>
</div>

但是,這將導致很多代碼重復:(。

通過在調用.attrs之后移動通用參數使它起作用。

const LinkAsButton = styled(Link).attrs
({
  as: 'button',
  className: 'btn btn-primary'
})<ButtonProps>`
  border: solid 1px red;
`;

現在,可以在JSX中設置ButtonProps中定義的任何道具

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM