React & TypeScript
之前看了一下 TypeScript 的知识,但是一直没有上手,最近开始结合 React 和 TypeScript 一起尝试了一下,感受还是很好的,所以写一下笔记。
环境配置没有参考其他东西,就是看了下 Webpack 和 TypeScript 的官方文档,使用 Webpack 进行构建还是比较简单的。
环境构建
创建一个项目目录,然后切换当前目录到项目目录下:
$ mkdir tsc && cd ./tsc
然后使用 npm 初始化项目:
$ npm init -y
然后创建一些项目文件:
$ mkdir build src
$ touch build/webpack.base.conf.js build/webpack.dev.conf.js build/webpack.prod.conf.js index.html src/index.tsx tsconfig.json
接下来,就可以安装一些依赖了:
$ npm i webpack webpack-cli webpack-merge webpack-dev-server -D
$ npm i html-webpack-plugin clean-webpack-plugin typescript ts-loader style-loader css-loader @types/react @types/react-dom -D
$ npm i react react-dom -S
可以注意到我们没有安装 babel 转译器,如果我们只写 .ts
或者 .tsx
文件,可以不安装 babel。如果要转译处理 .js
文件的话,还是要使用到 babel。
我们先写基础配置:
webpack.base.conf.js
const path = require('path');
const htmlWebpackPlugin = require('html-webpack-plugin');
const cleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
entry: path.resolve(__dirname, '../src/index.tsx'),
output: {
filename: '[name].[hash].js'
},
resolve: {
extensions: ['*', '.js', '.json', '.ts', '.tsx']
},
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
},
plugins: [
new htmlWebpackPlugin({
inject: true,
template: path.resolve(__dirname, '../index.html')
}),
new cleanWebpackPlugin(['dist'])
]
};
然后可以构造开发环境下的配置文件:
webpack.dev.conf.js
const merge = require('webpack-merge');
const path = require('path');
const baseConfig = require('./webpack.base.conf');
module.exports = merge(baseConfig, {
mode: 'development',
devtool: 'source-map',
devServer: {
port: 9999,
open: true,
contentBase: path.resolve(__dirname, '../dist')
}
});
然后添加 npm 脚本到 package.json
中:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack-dev-server --config ./build/webpack.dev.conf.js"
}
然后添加我们的 ts 配置到 tsconfig.json
:
{
"compilerOptions": {
"outDir": "./dist/", // 打包输出目录
"noImplicitAny": true, // 默认必须为变量指定类型
"module": "es6", // 使用 ESM 模块化方案
"target": "es5", // 代码编译成 ES 5
"jsx": "react", // 开启 JSX,使用 react 方式编译,如果要使用 babel 编译,那就将 jsx 设置为 ‘preserve’
"allowJs": true, // 允许编译 js 代码
"sourceMap": true, // 编译后同时产出 map 文件
"removeComments": true // 移除注释
}
}
更多的配置项解释,参考:翻译 | 开始使用 TypeScript 和 React。
写完了以后我们就可以添加内容到我们的开发文件中了:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
src/index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
ReactDOM.render(
<h1>Hello TSX!</h1>,
document.getElementById('root') as HTMLElement
);
可以注意到引入 React 和 ReactDOM 的方式和之前有一些不同。
另外由于 TypeScript 的强制转换符 <>
和 JSX 的元素相冲突,所以使用 as
作为强制转换符。
运行 npm run dev
,可以查看效果。
使用 TypeScript 以后,项目配置要稍微简单一点。配置好开发环境以后,就可以写代码啦!
第一个组件
我以一个 Header 组件为例,效果如下:
新建一个 Header.tsx
文件和一个 Header.css
文件到 src/components
下。
由于头部栏的标题文字应该是可以修改的,然后右边的 menu 应该是可以自定义的,所以这些数据应该都可以通过 props 传入我们的 Header 组件。
写我们的 Header 组件:
// Header.tsx
// 引入 React
import * as React from 'react';
// 引入我们的组件样式
import './Header.css';
// 定义的接口,用于规范 Header 组件的 props,向外界公开,
// 便于在其他组件中引用时实现这个接口,减少错误
export interface HeaderProps {
title: string; // 必须给定 title,一个 string 类型的值
menus?: MenuItemProps[]; // menus 是可选属性,是一个符合 MenuItemProps 接口规范的对象的数组
height?: string; // 问号都代表可选项
bgColor?: string;
}
// 这个接口定义了 MenuItem 组件的 props 规范,同时也定义了
// HeaderProps 中 menus 数组的元素的规范
interface MenuItemProps {
name: string; // 给定 menu 的名称
href: string; // 给定 menu 要跳转的链接
}
// 定义了 Header 组件的 state 的规范
interface HeaderState {
isVisible: boolean // 代表 Header 组件是否可见
}
// Header 组件
// 注意 React.Component 后面的泛型,就是我们上方定义的接口,它们分别制定了组件的 props 和 state 的规范
class Header extends React.Component<HeaderProps, HeaderState> {
// 指定组件实例的 state,必须符合 HeaderState 的规范
state = {
isVisible: true
}
render() {
const {
title,
menus = [],
height = '50px',
bgColor = 'lightblue'
} = this.props; // 从 props 获取值,其中可选项都有默认值
const style = {
height,
backgroundColor: bgColor
}; // 构造 Header 内联样式
return this.state.isVisible ? <div style={style} className="header">
<span>{title}</span>
<div className="header-menus">
{
menus.map(item => <MenuItem {...item}/>)
}
</div>
</div> : null;
}
}
// MenuItem 组件
// state 的规范是一个 object,未指定具体接口类型
class MenuItem extends React.Component<MenuItemProps, object> {
render() {
const { name, href } = this.props;
return <a className="header-menu-item" href={href} key={href}>
{name}
</a>
}
}
// 最后向外部暴露 Header 组件
export default Header;
可以看到 TypeScript 结合 React 其实很好用,尤其在规范 props 的时候很好用,能够避免很多编程时候的错误。而 IDE 的提示能够更加地方便我们开发。写起来何止舒服,简直舒服啊~
然后在 Header.css
写一下我们的样式:
html,
body,
div {
margin: 0;
padding: 0;
font-size: 16px;
}
.header {
font-size: 1.5rem;
line-height: 1rem;
padding: 1rem;
box-sizing: border-box;
position: relative;
}
.header-menus {
position: absolute;
right: 1rem;
top: 50%;
transform: translateY(-50%);
}
.header-menu-item {
margin: 0 .5rem;
}
这里仅仅是做个示例,排版没有在意太多的通用性,大家看看就好~
然后我们就可以在 index.tsx
中使用我们的 Header 组件了:
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import Header, { HeaderProps } from './components/Header'; // 引入接口规范和组件
// 构造 Header 组件的 props,必须符合 HeaderProps 接口规范。
// 在写的过程中 IDE 也能给我们很多的提示,方便了开发
const headerProps: HeaderProps = {
title: 'Hello TSX!',
menus: [{
name: 'menu1',
href: 'https://www.zhongdeming.fun'
}, {
name: 'menu2',
href: 'https://www.baidu.com'
}],
bgColor: 'lightyellow'
};
ReactDOM.render(
<Header {...headerProps}/>,
document.getElementById('root') as HTMLElement
);
这样一个组件就写完了,可以感受到 TypeScript 确实能够加速我们的开发,减少开发中的错误。
下面是一些利用 TypeScript 开发的时候 IDE 给出的提示的截图:
React & TypeScript的更多相关文章
- react + typescript 学习
react,前端三大框架之一,也是非常受开发者追捧的一门技术.而 typescript 是 javascript 的超集,主要特点是对 类型 的检查.二者的结合必然是趋势,不,已经是趋势了.react ...
- react typescript jest config (一)
1. initialize project create a folder project Now we'll turn this folder into an npm package. npm in ...
- React + Typescript领域初学者的常见问题和技巧
React + Typescript领域初学者的常见问题和技巧 创建一个联合类型的常量 Key const NAME = { HOGE: "hoge", FUGA: "f ...
- 【每天学一点-04】使用脚手架搭建 React+TypeScript+umi.js+Antd 项目
一.使用脚手架搭建项目框架 1.首先使用脚手架搭建React项目(React+TypeScript+Umi.js) 在控制台输入命令:yarn create @umijs/umi-app 2.引入An ...
- 前端自动化测试 —— TDD环境配置(React+TypeScript)
欢迎讨论与指导:) 前言 TDD -- Test-Drive Development是测试驱动开发的意思,是敏捷开发中的一项核心实践和技术,也是一种测试方法论.TDD的原理是在开发功能代码之前,先编写 ...
- React + TypeScript:元素引用的传递
React 中需要操作元素时,可通过 findDOMNode() 或通过 createRef() 创建对元素的引用来实现.前者官方不推荐,所以这里讨论后者及其与 TypeScript 结合时如何工作. ...
- react+typescript报错集锦<持续更新>
typescript报错集锦 错误:Import sources within a group must be alphabetized.tslint(ordered-imports) 原因:impo ...
- React + TypeScript 默认 Props 的处理
React 中的默认 Props 通过组件的 defaultProps 属性可为其 Props 指定默认值. 以下示例来自 React 官方文档 - Default Prop Values: clas ...
- react: typescript project initialize
Initialize the project create a folder project Now we’ll turn this folder into an npm package. npm i ...
随机推荐
- [日常] PHP设置 include_path 配置选项
动态设置php.ini中的include_path 配置选项: 两种方式set_include_path($new_include_path)ini_set('include_path',$new_i ...
- ActiveMQ Could not connect to broker URL
javax.jms.JMSException: Could not connect to broker URL: http://localhost:8161/. Reason: java.io.IOE ...
- Python import搜索的路径顺序
在程序中导入时,如下顺序 1.Python 标准库模块2.Python 第三方模块3.应用程序自定义模块 import的搜索顺序: 首先判断这个module是不是built-in即内建模块,如果是 ...
- python Django Ajax基础
升级版: ajax 创建多对多以及增加示例: views中的接收
- win8.1怎么安装iis
进入系统后,在左下角处点鼠标右键,再点击[程序和功能]如下图所示: 2 进入程序和功能界面后,点击[启用或关闭Windows功能] 在WINDOWS功能对话框中找到[internet in ...
- python学习之老男孩python全栈第九期_day016作业
1. 请利用filter()过滤出1~100中平方根是整数的数,即结果应该是: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] import math def func( ...
- 移动端地区选择mobile-select-area插件的使用方法
顾名思义,mobile-select-area插件就是使用在移动端上的进行地区选择的插件,而且使用方法简单,我就说我是怎么用的吧 一.准备工作 首先肯定要下载插件对应的css+js文件, 当你下载好这 ...
- 配置ftp服务器只能上传不能进行其他操作
又到期末考试了,今年当了数据挖掘助教,课程有一道编程大作业,需要搭建ftp服务器,实现文件上传,但是禁止下载重命名.服务器系统是ubuntu12.04 server,使用的ftp服务器也是linux下 ...
- Java集合 -- ArrayList集合及应用
JAVA集合 对象数组 集合类之ArrayList 学生管理系统 斗地主案例 NO.one 对象数组 1.1 对象数组描述 A:基本类型的数组:存储的元素为基本类型 int[] arr={1,2,3, ...
- centos安装redis,并设置开机自动启动项
安装Redis 1.下载.解压.编译.安装 下载.解压 https://redis.io/download 官网下载redis的*.tar.gz安装包.版本可根据自己需要下载. tar -zxvf r ...