Как предотвратить передачу опоры в расширенный компонент? - PullRequest
0 голосов
/ 29 мая 2020

Мой вопрос похож на этот , однако мне нужно ввести компонент. Я пробовал несколько способов, но все равно получаю ошибки.

Я не уверен, что проблема в моем понимании, или я что-то делаю не так? Вот что я пробовал:

  • Первый подход работает правильно, но выдает предупреждение: React не распознает опору isActive на элементе DOM
  • Второй и третий выдают ошибку 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 Ответ

1 голос
/ 29 мая 2020

Ваш второй подход выглядит хорошо, за исключением одной мелочи, которая вызывает ошибку: ref prop of TextareaAutosizeProps сталкивается с ref prop вашего стилизованного компонента.

refkey если на то пошло) является сложной «опорой» - вы передаете ее компоненту, как и любые другие реквизиты, но она не отображается в ваших реквизитах (например, если вы регистрируете их), она обрабатывается по-другому.

Если вы посмотрите на второй пример:

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'> {}

Если она вам нужна, вам нужно будет использовать функцию React.forwardRef ( подробнее об этом здесь ).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...