【问题标题】:How to prevent a prop from being passed to the extended component?如何防止道具被传递给扩展组件?
【发布时间】:2020-05-29 22:57:13
【问题描述】:

我的问题类似于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

【问题讨论】:

    标签: reactjs typescript styled-components


    【解决方案1】:

    您的第二种方法看起来不错,除了导致错误的一件小事:TextareaAutosizePropsref 属性与样式组件的ref 属性发生冲突。

    ref(和 key 就此而言)是一个棘手的“道具” - 你将它传递给组件,就像任何其他道具一样,但它不会出现在你的道具中(例如,如果你记录它们),它的处理方式不同。

    如果您查看第二个示例:

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

    你可以看到你的样式不是TextareaAutosize,而是匿名函数组件({ isActive, ...rest }: ExtendedProps) =&gt; ...。如果您将ref 传递给您的SecondTry 组件,它将不会出现在您的道具中({ isActive, ...rest }: ExtendedProps)。然而,当扩展TextareaAutosizeProps 时,您还说会有这样一个道具,它的类型是HTMLTextAreaElement

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

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

    interface ExtendedProps extends Props, Omit<TextareaAutosizeProps, 'ref'> {}
    

    如果您需要它,尽管您需要使用 React.forwardRef 函数(查看更多关于 here 的信息)。

    【讨论】:

    • 非常感谢:)
    猜你喜欢
    • 2018-10-09
    • 2022-01-03
    • 2021-10-28
    • 1970-01-01
    • 2018-08-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-19
    • 1970-01-01
    相关资源
    最近更新 更多