第一部分:将 Typescript 与 React 结合使用 第一部分:将 Typescript 与 React 结合使用

2025-06-05

第一部分:在 React 中使用 Typescript

第一部分:在 React 中使用 Typescript

编辑 React Typescript

第一部分:在 React 中使用 Typescript

学习使用 React 的 Typescript 可能颇具挑战性,就我而言,我甚至会咒骂微软,并尝试any各种变数。本系列的目标是记录我在 React 开发应用程序以及努力融入 Typescript 的过程中所学到的知识。就像许多事情一样,最初的学习曲线可能令人难以忍受,但一旦掌握了 Typescript,添加类型检查器就会带来回报。需要注意的是:这篇文章并非关于如何设置 Typescript。我们假设存在一个tsconfig.json文件,并且它会将我们的代码编译为有效的 JavaScript。

我们将通过创建计数器并在需要的地方添加类型来完成第一部分。

应用程序

首先,我们有一个应用程序的脚手架。

// Note, Typescript requires the whole React package to be imported.
// More information can be found: https://stackoverflow.com/a/37491916
import * as React from "react";

class App extends React.Component {
  public render() {
    return (
      <div>
        test
      </div>
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

看起来像一个有效的 React 类组件,但一些 Typescript 差异立刻显现出来。首先,由于 React 库没有默认导出,Typescript 要求我们导入整个包(import * as React from "react";)。其次,所有 React 方法都定义为publicprivate 或 protected不起作用),如render方法中所示。我们可以删除 **public * 键盘,组件仍将正常工作。我喜欢明确定义方法的作用域,以帮助区分我的方法和 React 的方法。通常,我将方法定义为privateunless 另有需要。这将强制方法的作用域仅限于组件,并防止不必要的副作用。

状态

我们需要一种存储计数器状态的方法。让我们来实现它。

// Note, Typescript requires the whole React package to be imported.
// More information can be found: https://stackoverflow.com/a/37491916
import * as React from "react";

interface IState {
  count: number;
}

class App extends React.Component<{}, IState> {
  public readonly state = {
    count: 0
  };

  public render() {
    return (
      <div>
        {this.state.count}
      </div>
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

这里发生了很多事情,因此我们将逐一进行分析。

界面
interface IState {
  count: number;
}
Enter fullscreen mode Exit fullscreen mode

首先,我们创建一个新的接口来定义组件状态的形状。

请注意,我们习惯于以大写字母“I”开头接口名称。这是从 C# 等 OOP 语言中借鉴而来的,以便我们更好地识别变量类型接口。

我采用的另一个做法是:用 PascalCase 命名 Typescript 类型,用 CamelCase 命名 Javascript 变量。这又是一个实用的命名方案,可以防止用户将类型定义当成可执行代码!

0.0001接下来,我们将组件的状态定义为一个字段 count。在 Typescript 中, float和 int没有区别10。为了表示某个值“类似数字”,我们赋予它 type number

类定义
class App extends React.Component<{}, IState> {
Enter fullscreen mode Exit fullscreen mode

React.Component(同样React.PureComponent)是泛型类型,允许我们提供组件 props 和 state 的结构children。Component 带有一些预定义属性(以及ref等等)。由于 App 没有任何 props,我们将使用一个空对象。React Typescript 定义将我们传入的类型与默认的 Component 类型相结合,因此即使使用空对象,继承的组件 props 仍然可用(例如 children 和 ref)。对于组件的状态,我们将告诉 Typescript 我们想要使用 IState 中定义的状态结构。

将其分解如下:

  • 定义仅具有状态的组件:React.Component<{}, IState>
  • 仅使用 props 定义一个组件:React.Component<IProps>
  • 定义状态和道具:React.Component<IProps, IState>
定义状态
public readonly state = {
  count: 0
};
Enter fullscreen mode Exit fullscreen mode

最后,我们定义组件的状态。记住,到目前为止,我们只告诉 Typescript我们状态的形状是什么。这是我们在 React 中定义它的实际值的地方。因为 React 需要状态,所以我们将其定义为public。此外,由于我们不希望任何人直接改变状态,所以我们添加了readonly。每当我们尝试将状态直接重新分配给一个值(例如)时,都会引发 Typescript 错误this.state.count = this.state.count + 1; // Error!。接下来,我们将公共只读变量定义为状态,并为其分配一个与我们在IState中定义的形状匹配的对象。由于我们React.ComponentIState定义为我们的状态形状,因此 Typescript 知道状态应该有一个带有数字值的count字段。

添加事件

让我们通过添加一些按钮和一个减少或增加计数的点击事件来完成我们的计数器。

// Note, Typescript requires the whole React package to be imported.
// More information can be found: https://stackoverflow.com/a/37491916
import * as React from "react";

interface IState {
  count: number;
}

class App extends React.Component<{}, IState> {
  public readonly state = {
    count: 0
  };

  private handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
    const type: string = event.currentTarget.title;

    this.setState(({ count }) => ({
      count: type === "decrement" ? count - 1 : count + 1
    }));
  };

  public render() {
    return (
      <div>
        <button title="decrement" onClick={this.handleClick}>
          -
        </button>
        {this.state.count}
        <button title="increment" onClick={this.handleClick}>
          +
        </button>
      </div>
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

最大的变化是增加了一种新方法。

private handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
Enter fullscreen mode Exit fullscreen mode

我们创建一个名为 的新私有方法handleClick,用于处理按钮点击事件。请注意,由于 React 使用合成事件,因此我们必须使用 React 的类型之一。该事件由鼠标点击触发,因此我们将使用React.MouseEvent。React.MouseEvent是一个泛型类型,它采用触发事件的元素类型。在我们的例子中,它是默认的 HTML 按钮元素(定义为HTMLButtonElement)。最后,我们根据按钮的标题增加或减少计数。

我们的计数器现在已经具备 TypeScript 类型了!

第二部分继续……

文章来源:https://dev.to/ganderzz/part-one-using-typescript-with-react-4i66
PREV
创建可重用组件的技巧
NEXT
函数式编程简介