Как использовать TypeScript с React

TypeScript – очень классный инструмент, как, впрочем, и React. Давайте попробуем использовать их вместе. В такой связке TypeScript предоставляет нам преимущества IntelliSense. Кроме того, внедрение TypeScript в свой проект– задача несложная, поскольку файлы можно обновлять постепенно, что не вызовет проблем в других частях проекта.

Давайте для начала создадим новый проект React и интегрируем в него TypeScript. Выполните следующие команды, чтобы сделать это:

# создайте новый каталог
$ mkdir react-typescript
# перейдите в него
$ cd react-typescript
# инициализируйте новый проект npm со стандартными настройками
$ npm init -y
# установите зависимости React
$ npm install react react-dom
# создайте index.html и App.tsx в каталоге src
$ mkdir src
$ cd src
$ touch index.html
$ touch App.tsx
# откройте каталог в редакторе
$ code .

Затем можно создать файл index.html со следующим содержимым:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>React + TypeScript</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
  <div id="main"></div>
  <script src="./App.tsx"></script>
</body>
</html>

В качестве упаковщика мы будем использовать Parcel, но вы можете выбрать webpack или другой инструмент, если хотите. Возможно, вы предпочитаете Create React App – мы поговорим об этом инструменте чуть позже. А сейчас добавим Parcel в наш проект:

# установите Parcel в DevDependencies
$ npm i parcel-bundler -D
# установите TypeScript
$ npm i typescript -D
# установите типы для React и ReactDOM
$ npm i -D @types/react @types/react-dom

Мы можем добавить в package.json новую задачу, которая запустит сервер разработки:

{
  "name": "react-typescript",
  "version": "1.0.0",
  "description": "An example of how to use React and TypeScript with Parcel",
  "scripts": {
    "dev": "parcel src/index.html"
  },
  "keywords": [],
  "author": "Paul Halliday",
  "license": "MIT"
}

Теперь мы можем заполнить файл Counter.tsx кодом для простого счетчика:

import * as React from 'react';

export default class Counter extends React.Component {
  state = {
    count: 0
  };

  increment = () => {
    this.setState({
      count: (this.state.count + 1)
    });
  };

  decrement = () => {
    this.setState({
      count: (this.state.count - 1)
    });
  };

  render () {
    return (
      <div>
        <h1>{this.state.count}</h1>
        <button onClick={this.increment}>Increment</button>
        <button onClick={this.decrement}>Decrement</button>
      </div>
    );
  }
}

Перейдем к файлу App.tsx. В нем можно загрузить счетчик:

import * as React from 'react';
import { render } from 'react-dom';

import Counter from './Counter';

render(<Counter />, document.getElementById('main'));

Наш проект уже можно запустить с помощью команды:

$ npm run dev

после чего можно получить доступ к нему по адресу http://localhost:1234.

Create React App и TypeScript

Если для запуска своих проектов вы предпочитаете использовать Create React App, вам будет приятно узнать, что CRA теперь поддерживает TypeScript прямо из коробки.

Просто используйте флаг –typescript при вызове команды create-response-app:

$ create-react-app my-new-app –typescript

Функции

Stateless компоненты или функции можно определять в TypeScript следующим образом:

import * as React from 'react';

const Count: React.FunctionComponent<{
  count: number;
}> = (props) => {
  return <h1>{props.count}</h1>;
};

export default Count;

Здесь мы используем React.FunctionComponent и определяем структуру ожидаемых свойств. В этом сценарии должно передаваться одно свойство по имени count, и мы определяем его в строке. Мы также можем определить его другими способами, создав интерфейс Props:

interface Props {
  count: number;
}

const Count: React.FunctionComponent<Props> = (props) => {
  return <h1>{props.count}</h1>;
};

Классы

Классы в TypeScript можно определить следующим образом:

import * as React from 'react';

import Count from './Count';

interface Props {}

interface State {
  count: number;
};

export default class Counter extends React.Component<Props, State> {
  state: State = {
    count: 0
  };

  increment = () => {
    this.setState({
      count: (this.state.count + 1)
    });
  };

  decrement = () => {
    this.setState({
      count: (this.state.count - 1)
    });
  };

  render () {
    return (
      <div>
        <Count count={this.state.count} />
        <button onClick={this.increment}>Increment</button>
        <button onClick={this.decrement}>Decrement</button>
      </div>
    );
  }
}

Свойства по умолчанию

Мы также можем определить defaultProps в сценариях, в которых свойства по умолчанию могут понадобиться. Давайте обновим наш пример со счетчиком, чтобы попробовать применить defaultProps:

import * as React from 'react';

interface Props {
  count?: number;
}

export default class Count extends React.Component<Props> {
  static defaultProps: Props = {
    count: 10
  };

  render () {
    return <h1>{this.props.count}</h1>;
  }
}

Также нужно прекратить передавать this.state.count в компонент Counter, иначе он перезапишет наше свойство по умолчанию:

render () {
  return (
    <div>
      <Count />
      <button onClick={this.increment}>Increment</button>
      <button onClick={this.decrement}>Decrement</button>
    </div>
  )
}

Заключение

Теперь у вас есть простой проект, настроенный для поддержки TypeScript и React, а также инструменты для создания ваших собственных функций, классов и других компонентов.

Читайте также: Работа с Create React App 2 и TypeScript

Tags: , ,

Добавить комментарий