【问题标题】:Spreading input props on styled component cause typescript error在样式化组件上传播输入道具会导致打字稿错误
【发布时间】:2021-08-03 16:52:39
【问题描述】:
现场演示链接:https://codesandbox.io/s/style-components-spread-error-cg189?file=/src/MySlider.tsx
我尝试将输入元素包装到反应组件中以应用自定义样式和标记。我想像使用任何其他输入元素一样使用它,通过使用value、onChange 等。但是打字稿不喜欢在样式输入上传播道具。我可以将道具投射到任何人身上,但我想知道为什么这是一个问题。谢谢!
const MyRange = styled.input.attrs({ type: 'range' as string })`
/* styles */
`;
export const MySlider: FC<HTMLProps<HTMLInputElement>> = (props) => {
return (
<>
<MyRange {...props} />
// ^^^^^^^ Types of property 'ref' are incompatible.
<span>{props.value}</span>
</>
);
};
【问题讨论】:
标签:
reactjs
typescript
styled-components
【解决方案1】:
HTMLProps<HTMLInputElement> 泛型类型包括不能分配给 styled-component 的类型。如果它是一个纯 HTML input 元素,那么这些类型将是有效的。相反,我建议您输入 MySlider 道具。
工作演示:
App.tsx
import * as React from "react";
import MySlider from "./MySlider";
import "./styles.css";
export default function App() {
const [value, setValue] = React.useState("10");
function onChange(e: React.ChangeEvent<HTMLInputElement>): void {
setValue(e.target.value);
}
return (
<div className="App">
<MySlider value={value} onChange={onChange} step="10" />
</div>
);
}
MySlider.tsx
import * as React from "react";
import styled from "styled-components";
const MyRange = styled.input.attrs({ type: "range" })`
appearance: none;
background: gray;
width: 100%;
height: 40px;
outline: none;
box-sizing: border-box;
margin: 0;
::-webkit-slider-thumb {
appearance: none;
height: 40px;
width: 40px;
background: red;
cursor: pointer;
}
`;
export type MySliderProps = {
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
value: string;
step: string;
};
export const MySlider = (props: MySliderProps): React.ReactElement => (
<>
<MyRange {...props} />
<span>{props.value}</span>
</>
);
export default MySlider;
小心混合数字和字符串。虽然您最初将 value 状态设置为数字,但它在 onChange 回调中设置为字符串。例如,event.target.value 是一个字符串(数字在 DOM 中存储为字符串)。将其保留为字符串或使用parseInt 将value 保留为数字:
function onChange(e: React.ChangeEvent<HTMLInputElement>): void {
setValue(parseInt(e.target.value, 10));
}
另外,有人推送到deprecate the usage of FC。