Начало работы с Typescript с помощью React Hook

Typescript — это следующий важный шаг в области фронтенд-разработки , и если вы хотите повысить свои навыки от младшего до среднего фронтенд-разработчика, то это необходимый навык. Typescript — это надстрочный индекс JavaScript, поэтому, если вы знаете JavaScript, вы уже на полпути! Что дает Typescript, так это более безошибочный код с проверкой типов во время выполнения и код, который можно легко документировать.

Эта статья предназначена для разработчиков, которые уже знают React и JavaScript и хотят перейти на Typescript, поэтому мы не будем заострять внимание на каких-либо концепциях React. Это ускоренный пост по пониманию основ использования Typescript с React Hooks.

В этой статье мы создадим простой личный список просмотра, в котором будут записываться введенные вами фильмы по их названию, рейтингу и обзору. Это выглядит примерно так. (Это немного стилизовано, но базовый код прост)

Изображение приложения

Настройка

Начнем с инициализации нашего проекта!

npx create-react-app --template typescript typescript-with-react

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

cd typescript-with-react/
code .
npm start

Структура вашего кода должна выглядеть примерно так

Структура кода

Обратите внимание на расширение файлов .ts или .tsx. Это означает, что эти файлы передаются в typescript формате.

Хорошо, теперь давайте перейдем к подробностям Typescript!

Обработка состояния

В typescript необходимо указать определения типов всех переменных и функций и то, что они возвращают.

  • Для обработки состояния в реакции вам необходимо сначала создать интерфейс, в котором вы укажете тип данных переменных.
  • В приведенном ниже примере мы создали интерфейс под названием IState(вы можете назвать его как угодно).
  • В интерфейсе IState мы напишем определение типа того, какими мы хотим видеть переменные состояния, которые в данном случае представляют собой массив объектов. Чтобы обозначить это, мы добавляем квадратную скобку после определения типа. А затем, используя useState, добавьте, <IState["form"]> что означает, что состояние должно принимать значения только в указанном формате (в данном случае формат IState, который принимает «форму» объекта в качестве входного формата)Государственный имидж

Мы экспортировали IState, чтобы позже использовать его в другом файле.

Альтернативный встроенный метод добавления состояния может быть следующим:

const [counter, setCounter] = useState<{name:string,rate:number,review?:string}[]>([])
  • В нашем проекте мы хотим, чтобы обзор был необязательным полем, а название фильма и рейтинг фильма — обязательным.
  • Таким образом, для проверки мы сделали review?:stringто, что вопросительный знак означает, что значение проверки может быть либо строкой, либо неопределенной. Однако для nameи rateу нас есть строгие определения типов, которые не принимают ничего, кроме назначенных определений типов.
  • Вы можете добавить более одного определения типа к переменной следующим образом:
inputValue:number | string | null

Здесь переменная inputValue может иметь числовой тип данных, строку или даже нулевое значение.

Примечание. Значение null и неопределенное — это не одни и те же типы данных.

Обработка Props

Для обработки props в react как отправляющая, так и принимающая сторона компонента должны четко объявить тип и количество задействованных переменных или функций. Typescript выдаст ошибку, если что-то отсутствует на отправляющей или принимающей стороне.

  • Это отправляющая сторона.
<List form={form} />
<Form form={form} setForm={setForm} />

Отправляем App.tsx один объект, т.е. form к List.tsx

  • Давайте теперь посмотрим на List принимающую сторону компонента.
import { IState as IProps } from "../App"

const List: React.FC<IProps> = ({ form }) => {
...
}
  • Список — это функциональный компонент react, который принимает реквизиты. В typescript показано, что мы добавляем React.FC<IProps> после List объявления компонента.
  • Мы можем импортировать IState под псевдонимом IProps, поскольку знаем, что определения типа объекта form точно такие же, как и у самого IState объекта.
  • Затем мы можем деструктурировать form параметры и использовать их в функциональном компоненте.

Во втором примере App.tsx мы отправляем один объект, т.е. form и одна функция, т.е. setFormto Form.tsx

Давайте теперь посмотрим на Form принимающую сторону компонента.

Компонент формы

Как вы можете видеть, в этом компоненте мы также импортировали его IStateпод псевдонимом Props, однако здесь мы внесли некоторые индивидуальные изменения.

  • Здесь мы создали новый интерфейс IProps, который определяет определение типа входящих реквизитов, поскольку нам нужно было указать тип setForm.
  • Упоминаем form: Props["form"], каким средствам следует присвоить форму, определение типа IState которой импортируется под псевдонимом Props
  • . Затем аналогичным образом мы сейчас сделаем это дляsetForm
Совет: чтобы узнать определения типов того, о чем вы не имеете ни малейшего представления, просто наведите указатель мыши на этот элемент и скопируйте определения типов.

наведите изображение

  • Поскольку мы уже объявили определения типов реквизитов как Props["form"], мы можем сократить определение типа setForm и вместо этого написать его следующим образом:
 setForm: React.Dispatch<React.SetStateAction<Props["form"]>>
  • Затем просто деструктурируйте formи setFormв параметрах функции Formи используйте ее в компоненте.

Обработка функций

В ответном Typescript вам необходимо указать тип вывода, который дает функция.

  • Здесь, в этом примере, мы вызвали mapList() функцию для сопоставления массива списка и выдачи строки таблицы в качестве вывода, которая является элементом JSX.

изображение функции

  • Чтобы указать тип вывода этой функции, добавьте : JSX.Element[]после параметров, что означает, что функция должна возвращать массив элементов JSX.
  • Интересно отметить, что мы написали вложенный оператор возврата, поскольку первый возврат указывает на функцию сопоставления.
  • Однако мы не должны возвращать функцию сопоставления, и поэтому машинописный текст выдал бы ошибку, если бы у нас был только один оператор возврата, поскольку мы указали тип возвращаемого значения как JSX.Element[].
  • Мы сделали вложенный оператор return внутри функции карты, чтобы он возвращал чистый элемент JSX, т.е. в этом случае строка таблицы.
Совет: если вы не уверены, какой тип возвращаемого значения, наведите указатель мыши на функцию, чтобы узнать тип возвращаемого значения.

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

const randomFunction = (): void => {
...
}

Обработка событий

Для обработки событий с помощью React Typescript мы рассмотрим следующие события DOM, вызываемые следующими элементами JSX в Form компоненте:

<input className="inputBox" type='text' name="name" value={input.name} onChange={(e) => handleChange(e)} />

<textarea className="inputBox" name="review" value={input.review} onChange={(e) => handleChange(e)}></textarea>

Здесь у input тега есть свойство DOM onChange, которое вызывается handleChange при возникновении события.

Для этого мы создаем функцию, которая знает, что она получит элемент HTML в параметрах.

 const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>): void => {
        setInput({
            ...input,
            [e.target.name]: e.target.value
        })
    }
  • Здесь мы заявляем, что это e будет тип React.ChangeEvent<HTMLInputElement>, который input будет отправлять тег.
  • А поскольку для поля обзора фильма мы используем тег textarea вместо тега ввода, это eтакже может быть React.ChangeEvent<HTMLTextAreaElement>.
  • Таким образом, все определение типа eможно записать как e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>.
  • Нам нужно добавить :void, чтобы указать, что эта функция ничего не будет возвращать.

Во втором примере мы рассмотрим onClickсобытие, вызываемое кнопкой отправки формы.

<button className="button" type="submit" onClick={(e) => handleClick(e)}>Submit</button>

const handleClick = (e: React.MouseEvent<HTMLButtonElement>): void => {
        e.preventDefault();
        if (!input.name || !input.rate) {
            return
        }
        setForm([...form, {
            name: input.name,
            rate: parseInt(input.rate),
            review: input.review
        }])
    }

Подобно handleChange функции, handleClick функция принимает правильное определение типа, e которым в данном случае является React.MouseEvent<HTMLButtonElement>.

Заключение

Вот и все, что касается этого ускоренного поста! Надеемся, это дало вам достаточно четкое представление о том, как использовать typescript в react. Продолжайте учиться и хорошего вам дня!