【问题标题】: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

我尝试将输入元素包装到反应组件中以应用自定义样式和标记。我想像使用任何其他输入元素一样使用它,通过使用valueonChange 等。但是打字稿不喜欢在样式输入上传播道具。我可以将道具投射到任何人身上,但我想知道为什么这是一个问题。谢谢!

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&lt;HTMLInputElement&gt; 泛型类型包括不能分配给 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 中存储为字符串)。将其保留为字符串或使用parseIntvalue 保留为数字:

    function onChange(e: React.ChangeEvent<HTMLInputElement>): void {
      setValue(parseInt(e.target.value, 10));
    }
    

    另外,有人推送到deprecate the usage of FC

    【讨论】:

      猜你喜欢
      • 2021-11-03
      • 2020-08-02
      • 2021-10-14
      • 2019-07-25
      • 2019-06-19
      • 2021-03-04
      • 2021-06-07
      • 1970-01-01
      • 2020-06-03
      相关资源
      最近更新 更多