React.forwardRef с generi c типом реквизита в потоке - PullRequest
1 голос
/ 26 февраля 2020

Я пытаюсь добавить React.forwardRef к уже существующему компоненту, который выглядит следующим образом:

type Props<T> = {
  someProp: T,
}

const Component = <T>({someProp}: Props<T>) => {...}

Теперь этот компонент использует Props<T>, где T - некоторый обобщенный c тип. У меня возникают трудности при добавлении React.forwardRef, и при этом нет ошибок и компромиссов при наборе текста.

Вот несколько вещей, которые я пробовал:

// Complains T doesn't exist
const Component = React.forwardRef<Props<T>, HTMLElement>((props, ref) => {...})
// Multiple errors
type Props<T> = {
    value: T,
    onChange: T => void,
}

const ChildComponent = <T>() => React.forwardRef<Props<T>, HTMLDivElement>((props, ref) => {
    return <div ref={ref}>123</div>;
});

const ParentComponent = () => {
    const [value, setValue] = React.useState(123);
    const onChange = newValue => setValue(newValue);

    return <ChildComponent />;
};

===============================================================================================

All branches are incompatible:
 • Either inexact AbstractComponent [1] is incompatible with exact React.Element [2].
 • Or AbstractComponent [1] is incompatible with React.Portal [3].
 • Or property @@iterator is missing in AbstractComponent [1] but exists in $Iterable [4].

    ../x.jsx
       7│   onChange: T => void,
       8│ }
       9│
      10│ const ChildComponent = <T>() => **React.forwardRef<Props<T>, HTMLDivElement>((props, ref) => {
      11│   return <div ref={ref}>123</div>;
      12│ })**;
      13│
      14│ const ParentComponent = () => {
      15│   const [value, setValue] = React.useState(123);

     /private/tmp/flow/flowlib_1eb3ba5b/react.js
 [2]  18│   | React$Element<any>
 [3]  19│   | React$Portal
 [4]  20│   | Iterable<?React$Node>;
        :
 [1] 297│   ): React$AbstractComponent<Config, Instance>;

Знаете ли вы, как использовать forwardRef с типами generi c в потоке?

Ответы [ 2 ]

1 голос
/ 27 февраля 2020

Вам нравится что-то подобное?

import React, { forwardRef } from 'react';

function GenericComponent<T>(props: { someProp: T }) {
  return null;
}

const ForwardedRefGenericComponent = forwardRef(
  (props, ref) => <GenericComponent ref={ref} {...props} />
);


function App() {
  // Examples of using ForwardedRefGenericComponent
  return (
    <div>
      <ForwardedRefGenericComponent someProp={42} />
      <ForwardedRefGenericComponent someProp={"abc"} />
      <ForwardedRefGenericComponent someProp={true} />
      <ForwardedRefGenericComponent someProp={["x", "y"]} />
      <ForwardedRefGenericComponent someProp={{ x: "y" }} />
    </div>
  );
}

Попробуйте Flow

Flow должен быть достаточно умным, чтобы вывести типы для вас, поэтому нет необходимости объявите типы явно для ForwardedRefGenericComponent.

0 голосов
/ 27 апреля 2020

Один раз универсальный c заводская банка радует поток

/* @flow */

import React from 'react';

type Props<T> = {|
  someProp: T
|};

const withRef = <T>() => React.forwardRef<Props<T>, any>((props, ref) => {
  return (<div ref={ref} />);
});

const Component = withRef<string>();  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...