Машинопись React.F C<Props> путаница - PullRequest
4 голосов
/ 30 января 2020

Я изучаю машинопись, и некоторые моменты меня смущают. Один бит ниже:

interface Props {
  name: string;
}

const PrintName: React.FC<Props> = (props) => {
  return (
    <div>
      <p style={{ fontWeight: props.priority ? "bold" : "normal" }}>{props.name}</p>
    </div>
  )
}


const PrintName2 = (props:Props) => {
  return (
    <div>
      <p style={{ fontWeight: props.priority ? "bold" : "normal" }}>{props.name}</p>
    </div>
  )
}

Для обоих функциональных компонентов выше, я вижу, TypeScript генерирует тот же код JS. Компонент PrintName2 кажется мне более удобным в плане читабельности. Интересно, в чем разница между этими двумя определениями, и есть ли кто-то, кто использует реактивные компоненты второго типа.

Ответы [ 4 ]

3 голосов
/ 30 января 2020

Первая версия добавит вам несколько типов - они взяты из React.F C

    interface FunctionComponent<P = {}> {
        (props: PropsWithChildren<P>, context?: any): ReactElement | null;
        propTypes?: WeakValidationMap<P>;
        contextTypes?: ValidationMap<any>;
        defaultProps?: Partial<P>;
        displayName?: string;
    }

Это полезно по нескольким причинам, но очевидным является случай, когда у вашего компонента есть дочерние элементы. Тогда вам не нужно вручную добавлять детский реквизит

2 голосов
/ 30 января 2020

Поскольку вы используете React и TypeScript, вы всегда должны использовать первый шаблон, так как он будет гарантировать, что ваш компонент будет более строго типизирован, поскольку это подразумевает, что PrintName будет иметь тип React Functional Component, и он принимает реквизиты типа Props.

const PrintName: React.FC<Props>

Полное определение интерфейса для функциональных компонентов вы можете прочитать в React TypeScript: хранилище .

Второй пример, который у вас есть обеспеченный не обеспечивает какую-либо форму типизации, за исключением того, что это функция, которая принимает набор параметров типа Props, и что она может возвращать что-либо вообще.

Поэтому написание

const PrintName2 = (props:Props)

сродни

const PrintName2: JSX.Element = (props:Props) 

, поскольку TypeScript определенно не может автоматически сделать вывод, что это функциональный компонент.

1 голос
/ 30 января 2020

Спасибо всем за ответы. Они верны, но я искал более подробную версию. Я провел еще какое-то исследование и обнаружил это на листе реакции-типов на github: https://github.com/typescript-cheatsheets/react-typescript-cheatsheet#reacttypescript -хитах

Компоненты функций
Их можно записать как обычно функции, которые принимают аргумент props и возвращают элемент JSX.

type AppProps = { message: string }; /* could also use interface */
const App = ({ message }: AppProps) => <div>{message}</div>;

Как насчет React.FC / React.FunctionComponent? Вы также можете написать компоненты с React.FunctionComponent (или сокращенно React.F C):

const App: React.FC<{ message: string }> = ({ message }) => (
  <div>{message}</div>
);

Некоторые отличия от версии «нормальной функции»:

Обеспечивает проверку типов и автозаполнение для stati c свойств, таких как displayName, propTypes и defaultProps. Однако в настоящее время существуют известные проблемы, связанные с использованием defaultProps с React.FunctionComponent. Подробности смотрите в этом выпуске - прокрутите вниз до нашего раздела defaultProps для ввода там рекомендаций.

Он предоставляет неявное определение дочерних элементов (см. Ниже) - однако существуют некоторые проблемы с неявным типом дочерних элементов (например, DefiniteTyped # 33006 ), и в любом случае, возможно, будет лучше определить стиль для компонентов, которые используют дочерние элементы.

const Title: React.FunctionComponent<{ title: string }> = ({
  children,
  title
}) => <div title={title}>{children}</div>;

В будущем он может автоматически помечать реквизиты как только для чтения, хотя это спорный вопрос, если объект реквизита Деструктурирован в списке параметров.

React.FunctionComponent явно указывает тип возвращаемого значения, в то время как нормальная версия функции неявна (или требует дополнительной аннотации).

В большинстве случаев это не имеет большого значения, какой синтаксис используется, но синтаксис React.F C немного более многословен без предоставления явного преимущества, поэтому приоритет был отдан синтаксису "обычной функции".

0 голосов
/ 01 мая 2020

React.FC не является предпочтительным способом ввода компонента React, есть ссылка .

Я лично использую этот тип:

const Component1 = ({ prop1, prop2 }): JSX.Element => { /*...*/ }

Короткий список из React.FC cons:

  1. Предоставляет неявное определение детей. Даже если вашему компоненту не нужны дочерние элементы, это может привести к ошибке.
  2. Не поддерживает универсальные шаблоны.
  3. Не работает с defaultProps правильно.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...