🙋🏻♀️Введение
⚛️Как использовать TypeScript с React?
🪞Типы свойств компонента React
🛑ReactNode против ReactElement
🪢Как печатать реквизиты с помощью TypeScript?
🪡Как вводить реквизит функционального компонента?
⛓React Hooks с помощью TypeScript
Введение
React — это популярная библиотека JavaScript для создания пользовательских интерфейсов. Он известен своей простотой, производительностью и гибкостью. Однако JavaScript — это язык с динамической типизацией, а это означает, что во время выполнения могут возникать ошибки. Здесь на помощь приходит TypeScript.
TypeScript добавляет в JavaScript статическую типизацию, что помогает обнаруживать ошибки до их возникновения. То есть TypeScript проверяет время компиляции. Это может улучшить качество и ремонтопригодность приложений React. Вот краткий обзор его использования.
Для компиляции кода TypeScript ищет tsconfig.json
в корневой папке для инструкций. Он загружает и использует настроенные параметры для сборки приложения.
Как использовать TypeScript с React?
- Чтобы добавить TypeScript в существующий проект, сначала установите его:
npm install --save typescript @types/node @types/react @types/react-dom @types/jest
or
yarn add typescript @types/node @types/react @types/react-dom @types/jest
- Создайте файл tsconfig.json вручную или с помощью команды терминала, а затем заполните его моим примером файла.
tsc --init
{ "compilerOptions": { "target": "ESNext", "useDefineForClassFields": true, "lib": ["DOM", "DOM.Iterable", "ESNext"], "allowJs": true, "skipLibCheck": true, "esModuleInterop": false, "allowSyntheticDefaultImports": true, "forceConsistentCasingInFileNames": true, "module": "ESNext", "moduleResolution": "Node", "resolveJsonModule": true, "isolatedModules": true, "noImplicitAny": false, "noEmit": true, "jsx": "react-jsx", "baseUrl": "./src/" }, "include": ["src"], "references": [{ "path": "./tsconfig.node.json" }] }
- Затем переименуйте любой файл в файл TypeScript (например,
src/index.js
вsrc/index.tsx
) и перезапустите сервер разработки! - Если для флага
allowJs
в файле tsconfig.js установлено значениеtrue
, это также позволит использовать файлы.js
. По умолчанию TypeScript поддерживает только.ts
файлов. - В проектах React с Vite в качестве сборщика
.tsx
файлов поддерживаются по умолчанию. Принимая во внимание, что в других сборщиках, таких как webpack, вам необходимо настроить его, чтобы включить использование расширения.tsx
. Например,
Для дальнейшей настройки измените расширение файла на .ts
или .tsx
в соответствии с требованиями.
- Используйте
.ts
при переименовании, когда вы создаете функции, классы, редукторы и т. д., которые не требуют использования синтаксиса и элементов JSX, тогда как расширение файла.tsx
используется при создании компонента React и использовании элементов и синтаксиса JSX. - Ошибки типа будут отображаться в той же консоли, что и ошибка сборки. Вам придется исправить эти ошибки типа, прежде чем продолжить разработку или построить свой проект.
Типы реквизитов компонента React
Реквизиты могут в основном иметь примитивные типы данных, такие как string
, number
и boolean
.
type Person = { // primitive types name: string, age: number, isUser: boolean }
Чтобы создать array
одного типа, используйте обозначение литерала массива ([]
) после типа.
type Person = { name: string[], // an array of string age: number, isUser: boolean }
Чтобы получить точное соответствие значения реквизита, используйте литералы. React выдаст ошибку, если значение свойства не соответствует определенному значению literal
.
type Props = { type: "old" | "new" | "latest", part: 1 | 2 | 3 }
Чтобы ввести реквизит object
,
type Props = { person: { name: string, age: number, isUser: boolean } }
Чтобы ввести children
prop, мы можем использовать ReactNode
.
React.PropsWithChildren
type берет вашу компонентную поддержку и возвращает тип объединения с соответствующим типом children
prop.
type PropsWithChildren<P> = P & { children?: ReactNode };
Чтобы ввести компонент React function
, в TypeScript есть React.FunctionComponent
или React.FC
, чтобы использовать его более короткую версию.
type Person = { name : string } const App:React.FC<Person> = ({name}) => { return ( <h1>{name}</h1> ) }
Хорошей новостью является то, что, поскольку TypeScript имеет предполагаемые функции типов, каждый раз вводить компоненты функции React не требуется.
Вводить элементы формы с помощью TypeScript довольно просто.
Функция handleChange
принимает событие типа React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
, что означает, что она может обрабатывать события как от элементов input
, так и от элементов textarea
.
ReactNode против ReactElement
Реагировать на элемент
Элемент React – это описание компонента, который можно отобразить на экране. Это простой объект JavaScript, представляющий элемент DOM или компонент.
Элементы React создаются с использованием синтаксиса JSX, который представляет собой расширение синтаксиса для JavaScript, которое позволяет вам писать HTML-подобный код в ваших файлах JavaScript. Например, следующий код JSX создает элемент React, представляющий заголовок:
const heading = <h1>Hello, World!</h1>;
Реагировать узел
С другой стороны, узел React — это более общий термин, который относится к любому объекту, который может быть отображен в модели React DOM.
Сюда входят не только элементы React, но также строки, числа, логические значения и другие объекты JavaScript. Например, следующий код создает узел React, который представляет собой строку:
const message = "Hello, World!"; const node = <div>{message}</div>;
Тип против интерфейса
Тип
type
определяет структуру объектов или сложных типов данных, которые мы используем в нашем коде.
TypeScript имеет тип данных any
, который представляет собой надмножество всех типов. Кроме того, он имеет типы данных built-in
и user-defined
.
Интерфейс
В TypeScript interface
дает подробную информацию о форме объекта. Компилятор TypeScript может использовать их для предоставления информации об именах свойств объектов и типах данных, которые могут содержать их значения.
Случай использования псевдонимов типов по сравнению с интерфейсом:
type
и interface
работают одинаково хорошо.
Если вы хотите добавить некоторые свойства/методы/события после определения стандартной структуры, предпочтительнее использовать interface
. Использование type
для этого выдает ошибку; как только это будет определено. type
нельзя изменить вне его определения. Слияние объявлений не будет работать в type
. С другой стороны, interface
является расширяемым (объединяемым).
С помощью type
и interface
вы можете расширить некоторые функции/свойства/методы существующей структуры. interface
предпочтительнее, так как это упрощает и делает более управляемым.
type
наиболее широко используется, если вам не нужна особая функция interface
для публичного показа. Кроме того, type
также используется для создания кортежей, объединений и пересечений. Кроме того, interface
отлично работает с классами. interface
может продолжать type
, а type
может пересекаться с interface
, если только не возникнут следующие сценарии:
Интерфейс не может расширять что-то, если он не знает входящий тип. Если вы сильно полагаетесь на «union» для большей части своего кода, тогда лучше используйте тип, а не интерфейс.
Вы также можете создавать псевдонимы типов и реализовывать их с классом. Класс не может реализовать тип объединения.
Как печатать реквизит с помощью TypeScript?
Props в React используются для хранения и передачи данных от родительского компонента к дочернему компоненту. Реквизиты играют жизненно важную роль, когда дело доходит до создания реальных приложений. Давайте посмотрим, как вводить некоторые реквизиты.
Его синтаксис довольно прост. Вам нужно добавить:
и нотацию литерала объекта {}
рядом с назначением деструктурирования реквизита children
в объявлении компонента. Кроме того, вы можете создать псевдоним Type для реквизита. Вы даже можете сделать реквизит optional
, добавив ?
после имени реквизита.
const app = ({ title }:{ title : string }) => ( <h1>{title}</h1> )
Ввод реквизитов события:
У нас есть различные категории событий. Давайте возьмем пример ввода события клика в качестве реквизита компонента. Реквизиты React также могут принимать такие функции, как onClick
и onChange
, поэтому вам может потребоваться ввести реквизиты функций. Компонент button
принимает событие click
в качестве реквизита и передает его элементу HTML Button.
Ввод реквизитов функционального компонента:
В TypeScript есть React.FunctionComponent
, или вы можете сказать React.FC
, чтобы ввести React Function Components.
Этот подход используется для доступа к дополнительному набору свойств, таких как propTypes, defaultProps, contextTypes и т. д., а также позволяет TypeScript узнать, что это компонент React.
Крючки для набора текста
Хуки поддерживаются в [@types/react
начиная с версии 16.8](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/a05cc538a42243c632f054e42eab483ebf1560ab/types/react/index.d.ts#L800-L1031). На самом деле не нужно набирать хук каждый раз. В большинстве случаев об этом позаботится вывод типа для простых значений.
хук useState
Однако, чтобы типизировать хуки, явно определите тип и используйте тип объединения:
const [person, setPerson] = useState<Person | null>(null); //to use later setPerson(newPerson);
Вы также можете использовать утверждения типов, если состояние инициализируется вскоре после установки и всегда имеет значение после:
В случае, когда состояние инициализируется вскоре после установки и после этого ему будет присвоено значение, хуки могут быть типизированы следующими способами:
const [person, setPerson] = useState<Person>({} as Person); // to use later setPerson(newPerson);
перехватчик useCallback
Печатать useCallbacks весело. Вы можете ввести хук useCallback точно так же, как вы вводите функции.
const myCallback = useCallback( (name: string, age: number) => { console.log(name, age) return { status: true } }, [...], );
Обратите внимание, что сигнатура функции может различаться в зависимости от версии React.
хук useReducer
Размеченные союзы прекрасно сочетаются с редьюсерами. Кроме того, они определяют тип возвращаемого значения, если вы его не укажете.
import { useReducer } from "react"; const initialState = { count: 0 }; type ACTIONTYPE = | { type: "increment"; payload: number } | { type: "decrement"; payload: string }; function reducer(state: typeof initialState, action: ACTIONTYPE) { switch (action.type) { case "increment": return { count: state.count + action.payload }; case "decrement": return { count: state.count - Number(action.payload) }; default: throw new Error(); } } function Counter() { const [state, dispatch] = useReducer(reducer, initialState); return ( <> Count: {state.count} <button onClick={() => dispatch({ type: "decrement", payload: "5" })}> - </button> <button onClick={() => dispatch({ type: "increment", payload: 5 })}> + </button> </> ); }
хук useRef
В TypeScript, в зависимости от того, полностью ли ваш параметр типа покрывает исходное значение или нет, useRef предоставляет ссылку, доступную только для чтения или изменяемую.
function Myfunction() { const divRef = useRef<HTMLDivElement>(null); useEffect(() => { if (!divRef.current) throw Error("divRef is not assigned"); doSomethingWith(divRef.current); }); return <div ref={divRef}>etc</div>; }
Укажите только тип элемента в качестве аргумента и используйте null
в качестве начального значения. В этом случае возвращаемая ссылка будет иметь .current
только для чтения, которым управляет React. TypeScript ожидает, что вы передадите эту ссылку реквизиту ref
элемента.
хук forwardRef
forwardRef — это компонент более высокого порядка, который позволяет компоненту передавать ссылку одному из своих дочерних элементов.
При использовании forwardRef важно определить типы свойств, которые передаются компоненту.
Обо мне:
Я разработчик программного обеспечения и Dev Advocate в DhiWise👩💻.
DhiWise позволяет создавать приложения React и Flutter с молниеносной скоростью без ущерба для качества кода и опыта разработчиков. Зайдите на платформу бесплатно, чтобы узнать больше, и не забудьте сообщить нам о своем опыте в нашем Discord🤘
Вы можете найти меня в LinkedIn и Twitter, чтобы быть в курсе последних технических обновлений о DhiWise. 😃