[英]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
在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
組件上指定特定於按鈕的道具(例如,禁用,表單等)。
在v4中,我希望達到相同的效果; 但是,我沒有成功確定如何去做。 根據最新的資料,我已經更新LinkAsButton
不再調用extend
或withComponent
,而是換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.