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

yizhihongxing

下面是 “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日

相关文章

  • JS实现的Object数组去重功能示例【数组成员为Object对象】

    下面是讲解“JS实现的Object数组去重功能示例【数组成员为Object对象】”的完整攻略。 一、背景介绍 在实际的开发过程中,我们经常会操作Object数组。而有时候,我们需要对一个Object数组进行去重操作,以避免出现重复数据。接下来,我们将会介绍针对这种情况下的JS实现的Object数组去重功能示例。 二、数组去重算法 去重算法是数组去重的核心,根…

    JavaScript 2023年5月27日
    00
  • javaScript中封装的各种写法示例(推荐)

    JavaScript中封装的各种写法示例,可以用于将代码进行模块化,提高代码复用性和可维护性。以下是常用的封装写法及示例说明: 函数封装 在JavaScript中,最常用的封装方式就是使用函数进行封装。函数封装可以将一段功能代码封装成一个具有独立作用的函数,以便多次调用、重复使用。下面是一个简单的加减乘除的函数封装示例: // 定义一个加减乘除的函数计算器 …

    JavaScript 2023年6月10日
    00
  • JavaScript中模拟实现jsonp

    JavaScript中模拟实现jsonp,需要遵循以下步骤: 1. 创建一个script标签 在DOM中创建一个script标签,并设置其src属性为需要跨域请求的URL,同时还需要设置一个callback参数,作为后端接口返回数据的回调函数名。 const script = document.createElement(‘script’); script.…

    JavaScript 2023年5月27日
    00
  • JS实现1000以内被3或5整除的数字之和

    实现1000以内被3或5整除的数字之和可以通过JavaScript的for循环语句、if条件语句以及数组等语法实现。下面是具体的实现步骤: 确定要使用的语法 由于要实现条件判断和循环操作,因此我们可以使用JavaScript的if条件语句和for循环语句。此外,我们还需要使用数组来存储符合条件的数字。 确定实现思路 首先,我们需要遍历1到1000之间的所有数…

    JavaScript 2023年5月28日
    00
  • JavaScript实现数组去重的7种方法

    JavaScript实现数组去重的7种方法 在JavaScript中,实现数组去重是一个常见的需求。下面介绍7种实现数组去重的方式。 1.使用 Set 使用ES6中的Set对象可以方便地实现数组去重,使用Set之后,将数组转换为Set之后,再将Set转换为数组即可。 const arr = [1, 2, 1, 2, 3] const newArr = Arr…

    JavaScript 2023年5月27日
    00
  • vue-router定义元信息meta操作

    vue-router是Vue.js官方的路由管理库,它可以帮助我们快速开发单页应用程序。在应用程序中,通常会有很多的页面,而有时候需要为这些页面增加一些标识,例如页面标题、页面关键字、页面描述等等。这些标识可以让搜索引擎更好地索引网站内容,也可以让用户更好地理解页面。 为此,vue-router提供了定义元信息meta的操作。元信息指我们在head标签中添加…

    JavaScript 2023年6月11日
    00
  • js验证email的正则

    JS验证 Email 的正则表达式是一项很重要的前端技能,本篇攻略旨在帮助想要掌握这项技能的读者们进行学习。 1. 什么是正则表达式 正则表达式是一种特殊的文本字符串,用于在文本中查找、替换和匹配符合某些特定规则的字符串。利用正则表达式可以简化很多复杂的字符串操作,使代码更加简洁高效。 2. 邮箱正则表达式规则 验证Email的正则表达式需要遵循RFC 53…

    JavaScript 2023年6月10日
    00
  • JavaScript常用脚本汇总(三)

    下面来详细讲解一下“JavaScript常用脚本汇总(三)”。 概述 本文是JavaScript常用脚本汇总系列的第三篇,主要介绍一些常用的JavaScript脚本及其用法,希望能为广大JavaScript开发者提供一些参考和帮助。本文内容主要包括:局部刷新页面、自动保存草稿、获取浏览器版本信息和判断是否为移动端等。 局部刷新页面 在传统的Web应用程序中,…

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