react结合typescript 封装组件实例详解

下面是 “react结合typescript 封装组件实例详解”的完整攻略。

一、为什么要使用TypeScript

TypeScript 是 JavaScript 的一个超集,它可以为 JavaScript 提供类型检查和其他一些新特性。TypeScript 具有以下优点:

  • 代码更加健壮,更容易维护。
  • 更好的智能提示和 IDE 支持。
  • 更容易对代码进行重构。
  • 更好的语言规范约束,可以防止出现一些常见的错误。
  • 易于与其他类型需要 TypeScript 支持的框架交互。

二、React 和 TypeScript 结合使用

为了可以更好的使用 React TypeScript,我们需要安装依赖包。

npm install react react-dom @types/react @types/react-dom typescript --save-dev

以上命令会安装 React 和 TypeScript 以及必要的类型定义文件。

接下来,在你的项目中创建一个 src 文件夹,并且创建一个 App.tsx 文件。在这个文件中,我们可以使用 TypeScript 和 React 构建我们的组件。以下是一个简单的例子:

import * as React from 'react';

interface Props {
    name: string;
}

const App: React.FC<Props> = ({ name }) => {
    return (
        <div>
            <h1>Hello, {name}!</h1>
        </div>
    );
};

export default App;

在上面的代码中,我们定义了一个 Props 的接口,它规定了组件需要传入一个名为 name 的属性。然后,我们使用 React.FC 类型定义了一个函数组件,名称为 App,它接受一个 Props 参数,并返回一个 JSX 元素。

三、如何封装 TypeScript 组件

较为常见的做法是,把类组件和函数式组件的特定结构合并在一起,这有助于保证每个组件都具有一致的 API。

这里我们以类组件的封装为例,将完成一个带计时器的数字输入框扩展按钮组件。

  • 定义属性类型 Props
interface Props {
  /** 输入框值 */
  value?: string;
  /** 输入框value的变化回调 */
  onChange?: (val: string) => void;
  /** 输入框通用属性 */
  [key: string]: any;
  /** 自动计时时长,单位毫秒 */
  autoCountDuration?: number;
}

以上属性中 autoCountDuration 是可选属性,其他以及通用属性皆为必填。

  • 定义组件状态 State
interface State {
  count: number;
}
  • 类组件实现
class InputBox extends React.Component<Props, State> {
  /** 计时器 */
  private timer?: NodeJS.Timeout;
  /** 计数器 */
  private count = 0;

  constructor(props: Readonly<Props>) {
    super(props);
    this.state = {
      count: 0,
    };
  }

  componentDidUpdate(
    prevProps: Readonly<Props>,
    prevState: Readonly<State>
  ) {
    const { autoCountDuration } = prevProps;
    if (this.props.autoCountDuration !== autoCountDuration) {
      // 清除旧时器
      clearTimeout(this.timer!);
      if (typeof this.props.autoCountDuration === 'number') {
        this.startIntervalCount();
      }
    }
  }

  /**
   * 自动计时数数,使用类模式
   */
  private startIntervalCount() {
    this.count = 0;
    this.timer = setInterval(() => {
      this.count += 1;
      this.setState({ count: this.count });
    }, this.props.autoCountDuration!);
  }

  /**
   * 值变化事件
   *
   * @param e
   */
  private onChange(e: React.ChangeEvent<HTMLInputElement>) {
    const { onChange } = this.props;
    if (onChange) {
      onChange(e.target.value);
    }
  }

  /** 点击按钮 */
  private onBtnClick() {
    alert('你点击了扩展按钮!');
  }

  render() {
    const { count } = this.state;
    const { value, ...rest } = this.props;
    const btnStyle: React.CSSProperties = {
      marginLeft: '8px',
    };
    return (
      <div>
        <input
          {...rest}
          value={value || ''}
          onChange={this.onChange.bind(this)}
        />
        <button style={btnStyle} onClick={this.onBtnClick.bind(this)}>
          操作
        </button>
        <span>自动计数:</span>
        <span>{count}</span>
      </div>
    );
  }
}

上述代码中,我们首先声明了一个 class 类组件的名称和一个泛型接口 Props,它是一个对象,它用于存储类组件的属性。接着,在定义组件内部状态的声明。

在组件的构造函数中,我们用 super(props) 调用 React.Component 的构造函数,并使用 componentWillMount 设置本地 state。由于 constructor 仅能使用 super 和 state,所以它不适合进行本地状态初始化,因此我们采用 componentWillMount 进行设置。

这里我们需要注意的是,在 componentWillUnmount 函数中一定要记得清除 this.timer,以免造成内存泄露。

四、示例

下面我们来看一个示例:实现一个 TodoList 组件,包括添加和删除条目的功能。

import React, { useState } from 'react';

export type TodoItemType = {
  id: string;
  text: string;
}

interface Props {
  initData?: TodoItemType[];
}

const TodoList: React.FC<Props> = ({ initData = [] }) => {
  const [todoList, setTodoList] = useState<TodoItemType[]>(initData);
  const [textInputVal, setTextInputVal] = useState('');

  const handleTextInput = (e: React.ChangeEvent<HTMLInputElement>) => {
    const val = e.target.value;
    setTextInputVal(val);
  };

  const handleAddTodoItem = () => {
    setTodoList((preList) => [
      ...preList,
      {
        id: String(Date.now() + Math.random() * 1000),
        text: textInputVal,
      },
    ]);
    setTextInputVal('');
  };

  const handleDeleteTodoItem = (id: string) => {
    setTodoList((preList) => preList.filter((item) => item.id !== id));
  };

  return (
    <div>
      <h2>TodoList</h2>
      <div>
        <input value={textInputVal} onChange={handleTextInput} />
        <button onClick={handleAddTodoItem}>添加</button>
      </div>
      <ul>
        {todoList.map((item) => (
          <li key={item.id}>
            <span>{item.text}</span>
            <button onClick={() => handleDeleteTodoItem(item.id)}>删除</button>
          </li>
        ))}
      </ul>
    </div>
  );
};

export default TodoList;

上述代码中,我们首先定义了一个 TodoItemType 类型,它描述了一个待办事项的结构。接着,我们定义了一个 Props 接口,它规定了组件需要传入一个名为 initData 的属性,它是一个 TodoItemType 数组类型,作为组件初始化的列表数据。

在组件中,我们使用 useState Hook 定义了 todoListtextInputVal 状态。然后,我们将 textInputVal 绑定到 <input> 元素,这样我们就能够实时得到用户输入的文本信息。

在添加函数 handleAddTodoItem 中,我们使用 setTodoList 进行列表的更新。通过展开运算符将前面的列表数据和新增数据合并为一个新的数组并更新到状态中。

最后,我们使用了 map 函数,渲染出列表中的各个项。每一项都会有一个删除按钮,点击时会触发 handleDeleteTodoItem,将待删除的项从待办事项列表中移除。

五、总结

本文介绍了如何利用 TypeScript 封装 React 组件。在这个例子中,我们定义了一个 <InputBox> 组件,并为其添加了计时器和扩展按钮功能,以及一个 <TodoList> 组件,它实现了添加和删除待办事项的功能。在这个过程中,我们学习了如何使用 TypeScript 定义组件 Props 和 State,以及如何在组件中使用 Hook 状态管理数据。最后,我们展示了如何使用 TypeScript 编写 React 组件的注意事项和核心代码。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:react结合typescript 封装组件实例详解 - Python技术站

(0)
上一篇 2023年6月10日
下一篇 2023年6月10日

相关文章

  • javascript生成/解析dom的CDATA类型的字段的代码

    要生成/解析包含CDATA类型的字段,我们需要使用Javascript中的 DOM 操作。下面是生成CDATA类型字段的完整攻略: 生成CDATA类型字段的代码 步骤1:创建一个包含CDATA类型字段的元素 我们可以使用 Document.createElement() 方法创建一个新的元素,然后使用 Document.createCDATASection(…

    JavaScript 2023年6月10日
    00
  • elementUI Tree 树形控件的官方使用文档

    ElementUI Tree 树形控件是基于Vue.js的一款可折叠的树形菜单组件,用于显示有层次结构的数据。以下是官方使用文档的完整攻略: 树形控件的基本使用 可以使用<el-tree> 标签将树形控件引入到页面中,并传入相应的数据。 其中需要传入的数据包括data和props。 以下是一个简单的示例: <template> &lt…

    JavaScript 2023年6月10日
    00
  • JS判断元素是否存在数组中的5种方式总结

    下面是关于“JS判断元素是否存在数组中的5种方式总结”的详细讲解攻略: 1. 使用indexOf方法 indexOf()方法是用来查找一个元素在数组中第一次出现的位置。如果该元素存在,indexOf()方法会返回该元素在数组中的索引值,否则会返回-1。 下面是一个使用indexOf()方法来判断数组中是否包含某个元素的示例: const arr = [1, …

    JavaScript 2023年5月27日
    00
  • 学习JavaScript设计模式(策略模式)

    学习JavaScript设计模式之策略模式 什么是策略模式?策略模式是一种行为设计模式,它能让你定义一系列算法,将它们封装到一个个独立的类中,可以使它们相互替换。策略模式使得算法可以独立于使用它们的客户端而变化。 在JavaScript中,策略模式通常是通过定义不同的函数来实现的。根据需要,你可以将算法添加到一个对象中,然后把这个对象传递给执行某个方法的函数…

    JavaScript 2023年5月18日
    00
  • jquery的$getjson调用并获取远程的JSON字符串问题

    当我们希望从远程的JSON文件中获取数据时,可以使用jQuery库中的getJSON函数。下面,我将为大家详细讲解“jQuery的getJSON调用并获取远程的JSON字符串问题”的完整攻略,包括使用方法和示例说明。 使用方法 getJSON函数是jQuery库中的一个方法,其作用是从服务器获取JSON格式数据,其基本语法格式如下所示: $.getJSON(…

    JavaScript 2023年5月27日
    00
  • Area 区域实现post提交数据的js写法

    Area 区域是HTML表单元素的一种。它允许在一个可编辑的区域内输入文本或代码。使用JavaScript,我们可以使用它来实现提交数据的功能,这些数据可以使用POST方法发送到服务器。 以下是实现Area 区域Post提交数据的基本步骤: 创建一个表单元素,其中包含一个Area 区域,指定一个ID用于JavaScript操作。 <form> &…

    JavaScript 2023年6月11日
    00
  • JavaScript获取中英文混合字符串长度的方法示例

    哦,好的!那我来详细讲解一下“JavaScript获取中英文混合字符串长度的方法示例”的完整攻略。 什么是中英文混合字符串? 所谓中英文混合字符串,是指字符串中既包含中文字符,也包含英文字符。 获取中英文混合字符串长度的方法 JavaScript 中提供了多种方法来获取字符串长度,但对于中英文混合字符串,有些方法并不能完全正确地计算其长度。下面介绍两种可行的…

    JavaScript 2023年5月28日
    00
  • 突袭HTML5之Javascript API扩展2—地理信息服务及地理位置API学习

    突袭HTML5之Javascript API扩展2—地理信息服务及地理位置API学习 介绍 本篇文章主要介绍HTML5中地理信息服务及地理位置API的使用,其中包括了以下内容:1. 地理信息服务的概述2. 地理位置API的基本知识和使用方法3. 常用的地理位置API实例 地理信息服务概述 地理信息服务是指向用户提供有关地理位置信息及相关服务的技术和应用。在H…

    JavaScript 2023年6月11日
    00
合作推广
合作推广
分享本页
返回顶部