如何防止道具传递到扩展组件?

时间:2020-05-29 14:30:39

标签: reactjs typescript styled-components

我的问题类似于this one,但是我需要输入一个组件。我尝试了多种方法,但仍然出现错误。

我不确定问题是否出在我的理解范围内,还是我做错了什么?这是我尝试过的:

  • 第一种方法可以正常工作,但会发出警告:React无法识别DOM元素上的isActive道具
  • 第二次和第三次抛出TS错误:此调用没有重载。
import * as React from "react";
import TextareaAutosize, { TextareaAutosizeProps } from "react-textarea-autosize";
import styled from "styled-components";

interface Props {
  isActive?: boolean;
}

interface ExtendedProps extends Props, TextareaAutosizeProps {}

const FirstTry = styled(TextareaAutosize)<Props>`
  color: ${({ isActive }) => (isActive ? "red" : "blue")};
`;

const SecondTry = styled(({ isActive, ...rest }: ExtendedProps) => (
  <TextareaAutosize {...rest} />
))`
  color: ${({ isActive }) => (isActive ? "red" : "blue")};
`;

const ThirdTry = ({ isActive, ...rest }: ExtendedProps) => {
  const Foo = styled(TextareaAutosize)<TextareaAutosizeProps>`
    color: ${isActive ? "red" : "blue"};
  `;

  return <Foo {...rest} />;
};

export default function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <FirstTry isActive minRows={3} />
      {/* FirstTry - Warning: React does not recognize the `isActive` prop on a DOM element */}
      <SecondTry isActive minRows={3} />
      <ThirdTry isActive minRows={3} />
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

链接到沙箱: https://codesandbox.io/s/zen-cdn-lp8pl?file=/src/App.tsx

1 个答案:

答案 0 :(得分:1)

您的第二种方法看起来不错,除了会导致错误的一小件事:ref的{​​{1}}属性与样式组件的TextareaAutosizeProps属性冲突。

ref(和ref)是一个棘手的“道具”-您像将其传递给其他道具一样将其传递给组件,但它不会出现在道具中(如果您记录了它们)例如),它的处理方式有所不同。

如果您看第二个示例:

key

您会看到您不是在样式const SecondTry = styled(({ isActive, ...rest }: ExtendedProps) => ( <TextareaAutosize {...rest} /> ))` color: ${({ isActive }) => (isActive ? "red" : "blue")}; `; ,而是在使用匿名功能组件TextareaAutosize。如果将({ isActive, ...rest }: ExtendedProps) => ...传递给ref组件,它将不会出现在道具(SecondTry)中。但是,在扩展{ isActive, ...rest }: ExtendedProps时,您还说会有一个道具,它的类型为TextareaAutosizeProps

所以我可以根据您的需要考虑两种解决方案:

如果您不需要HTMLTextAreaElement上的ref道具,则可以从道具中省略它:

SecondTry

尽管需要,但仍需要使用interface ExtendedProps extends Props, Omit<TextareaAutosizeProps, 'ref'> {} 函数(有关here的更多信息)。