React Typescript 笔记【1】

154 阅读1分钟

Components

import React from 'react'

// Written as a function declaration
function Heading(): React.ReactNode {
  return <h1>My Website Heading</h1>
}

// Written as a function expression
const OtherHeading: React.FC = () => <h1>My Website Heading</h1>

Props

import React from 'react';

interface Props {
  name: string;
  color: string;
}

type OtherProps = {
  name: string;
  color: string;
}

// Notice here we're using the functiion declaration with the interface Props
function Heading({ name, color }: Props): React.ReactNode {
  return <h1>My Website Heading</h1>
}

// Notice here we're using the function expression with the type OtherProps
const OtherHeading: React.FC<OtherProps> = ({ name, color }) => {
  return <h1>My Website Heading</h1>
}

当涉及到 type 或 interface 时,我们建议遵循 react-typescript-cheatsheet 社区提出的指南:

  • 在编写库或第 3 方环境类型定义时,始终使用 interface 作为公共 API 的定义
  • 考虑在 React 组件 Props 和 State 使用 type,因为它更受限制。
AspectTypeInterface
Can describe functions
Can describe constructors
Can describe tuples
Interfaces can extend it⚠️
Classes can extend it🚫
Classes can implement it (implements)⚠️
Can intersect another one of its kind⚠️
Can create a union with another one of its kind🚫
Can be used to create mapped types🚫
Can be mapped over with mapped types
Expands in error messages and logs🚫
Can be augmented🚫
Can be recursive⚠️

Extending Component Props

type

import React from 'react';

type ButtonProps = {
  /** the background color of the button */
  color: string;
  /** the text to show inside the button */
  text: string;
}

type ContainerProps = ButtonProps & {
  /** the height of the container (value used with 'px') */
  height: number;
}

const Container: React.FC<ContainerProps> = ({ color, text, height}) => {
  return <div style={{ backgroundColor: color, height: `${height}px` }}>{text}</div>
}

interface

import React from 'react';

interface ButtonProps {
  /** the background color of the button */
  color: string;
  /** the text to show inside the button */
  text: string;
}

interface ContainerProps extends ButtonProps {
  /** the height of the container (value used with 'px') */
  height: number;
}

const Container: React.FC<ContainerProps> = ({ color, height, width, text }) => {
  return <div style={{ backgroundColor: color, height: `${height}px` }}>{text}</div>
}

Handling Form Events

import React, { useState } from 'react';

const MyInput = () => {
  const [value, setValue] = useState('');
  
  function onChange(e: React.ChangeEvent<HTMLInputElement>) {
    setVaue(e.target.value)
  }
  
  return <input value={value} onChange={onChange} id="input-example"/>
}

Third-party Libraries

#yarn
yarn add @types/<package-name>
​
#npm
npm install @types/<package-name>
  • Should these be saved as dependencies or devDependencies in my package.json?

    简短的回答是“视情况而定”。大多数情况下,如果您正在构建 Web 应用程序,它们可以归入 devDependencies。但是,如果您正在使用 TypeScript 编写 React 库,您可能希望将它们作为依赖项包含在内。

  • What happens if they don’t have a @types package?

    two options:

    1. Add a basic declaration file
    2. Add a thorough declaration file

参考文档

React with TypeScript: Best Practices

【译】React+TypeScript 最佳实践

typescript-cheatsheets

推荐阅读

[译] - 当众学习 - 最快的学习方式

Learn In Public