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日

相关文章

  • JS实现字符串转驼峰格式的方法

    JS实现字符串转驼峰格式的方法,可以通过使用正则表达式和replace方法来实现。下面是一个完整的攻略: 使用正则表达式和replace方法实现 步骤如下: 通过正则表达式匹配所有需要转换为驼峰格式的字符串。 javascript/[-_]\w/g [-_]表示要匹配的分隔符可以是 – 或 _ ,方括号[]表示单字符匹配 \w表示匹配任何字母数字字符,等价于…

    JavaScript 2023年5月28日
    00
  • js格式化时间和js格式化时间戳示例

    下面是我对“js格式化时间和js格式化时间戳示例”的详细讲解。 什么是js格式化时间和js格式化时间戳? 在网站开发过程中,时间是一个很常见的数据类型。js格式化时间指的是将时间戳转化为人类可读的时间字符串,而js格式化时间戳指的是将时间字符串转化为时间戳。 如何使用js格式化时间? 在js中,可以使用Date对象来处理时间。下面是一个使用js格式化时间的示…

    JavaScript 2023年5月27日
    00
  • javascript json2 使用方法

    下面是关于JavaScript中json2库的使用方法的详细攻略: 1. 什么是json2库? json2是一种JSON格式的解析器和序列化器的集合。该库把JSON格式转换为JavaScript对象,以及JavaScript对象转换成JSON格式。其中,json2.js是针对JSON对象在浏览器中的兼容性做的一个修复,当JSON对象在浏览器中使用时,当这个对…

    JavaScript 2023年5月27日
    00
  • 基于Cookie常用操作以及属性介绍

    下面我将详细讲解基于Cookie常用操作以及属性介绍的攻略。 1. 什么是Cookie 定义:Cookie 是一种存储在客户端的小文本文件,由浏览器自动管理,包含网站相关信息。 特点: 借助 HTTP 协议,在客户端和服务端之间传输; 客户端可通过 JavaScript 操作,实现与服务端的数据交互; Cookie 是一次性的(默认情况下)。它只存在一个时间…

    JavaScript 2023年6月11日
    00
  • JavaScript常用数组去重的方法及对比详解

    JavaScript常用数组去重的方法及对比详解 在JavaScript开发中,常常需要对数组进行去重操作。本文将详细介绍JavaScript常用的数组去重方法,并对它们进行比较和详细解释。 一、方法1:双重循环去重法 方法描述 通过双重循环遍历数组,把数组中的每个元素依次与之后的每个元素相比较,如果发现重复的元素,则把后面的元素从数组中删除。 示例代码 f…

    JavaScript 2023年5月27日
    00
  • JavaScript性能优化之函数节流(throttle)与函数去抖(debounce)

    JavaScript性能优化之函数节流与函数去抖 函数节流(throttle)和函数去抖(debounce)都是 JavaScript 中常用的性能优化技巧。它们都是用来解决频繁触发回调函数导致过多计算使页面出现卡顿或资源浪费的问题。 函数节流 throttle 函数节流的基本思路是:在一定时间间隔内,只执行一次函数。通过这种方式,可以减少计算次数,提升性能…

    JavaScript 2023年5月27日
    00
  • JavaScript事件委托

    JavaScript 事件委托是一种常用的编程技巧,它可以避免为每个元素添加事件监听器。事件委托背后的思想是,将事件监听器添加到其父元素上,而不是为每个子元素添加监听器。当事件触发时,事件将从子元素冒泡到其父元素,由父元素的事件监听器处理。这种技巧可以减少代码量,提高性能。 以下是一个完整的 JavaScript 事件委托攻略: 1. 理解事件冒泡和捕获 事…

    Web开发基础 2023年3月30日
    00
  • JavaScript中数组对象的那些自带方法介绍

    下面就为大家详细介绍JavaScript中数组对象的自带方法。 1. 增加、删除、修改元素 push、pop、shift、unshift方法 push方法:在数组的末尾插入一个或多个元素,并返回数组新的长度。 pop方法:删除数组的最后一个元素,并返回该元素的值。 shift方法:删除数组的第一个元素,并返回该元素的值。 unshift方法:在数组的开头插入…

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