1- 这个快速上手指南将会教你如何将TypeScript和 [ React] ( http://facebook.github.io/react/ ) 结合起来使用。
2- 到最后,你将得到 :
1+ 这篇快速上手指南会教你如何将TypeScript与 [ React] ( http://facebook.github.io/react/ ) 结合起来使用。
2+ 在最后,你将学到 :
33
4- * 一个使用了TypeScript和React的工程
4+ * 使用TypeScript和React创建工程
55* 使用[ TSLint] ( https://github.com/palantir/tslint ) 进行代码检查
66* 使用[ Jest] ( https://facebook.github.io/jest/ ) 和[ Enzyme] ( http://airbnb.io/enzyme/ ) 进行测试,以及
77* 使用[ Redux] ( https://github.com/reactjs/react-redux ) 管理状态
88
9- 我们将使用 [ create-react-app] ( https://github.com/facebookincubator/create-react-app ) 工具快速搭建工程环境。
9+ 我们会使用 [ create-react-app] ( https://github.com/facebookincubator/create-react-app ) 工具快速搭建工程环境。
1010
11- 我们这里假设你已经在使用 [ Node.js] ( https://nodejs.org/ ) 和[ npm] ( https://www.npmjs.com/ ) 。
12- 还需要你对 [ React的基础知识] ( https://facebook.github.io/react/docs/hello-world.html ) 稍做了解 。
11+ 这里假设你已经在使用 [ Node.js] ( https://nodejs.org/ ) 和[ npm] ( https://www.npmjs.com/ ) 。
12+ 并且已经了解了 [ React的基础知识] ( https://facebook.github.io/react/docs/hello-world.html ) 。
1313
1414# 安装create-react-app
1515
1616我们之所以使用create-react-app是因为它能够为React工程设置一些有效的工具和权威的默认参数。
17- 它仅仅是一个用来搭建React工程的命令行工具 。
17+ 它仅仅是一个用来搭建React工程的命令行工具而已 。
1818
1919``` shell
2020npm install -g create-react-app
2121```
2222
2323# 创建新工程
2424
25- 让我们创建一个叫做 ` my-app ` 的新工程:
25+ 让我们首先创建一个叫做 ` my-app ` 的新工程:
2626
2727``` shell
2828create-react-app my-app --scripts-version=react-scripts-ts
2929```
3030
3131[ react-scripts-ts] ( https://www.npmjs.com/package/react-scripts-ts ) 是一系列适配器,它利用标准的create-react-app工程管道并把TypeScript混入进来。
3232
33- 到这里,工程结构应如下所示 :
33+ 此时的工程结构应如下所示 :
3434
3535``` text
3636my-app/
@@ -46,24 +46,24 @@ my-app/
4646
4747注意:
4848
49- * ` tsconfig.json ` 包含了这们工程里TypeScript特定的选项 。
50- * ` tslint.json ` 保存了将要使用的代码检查器的设置 ,[ TSLint] ( https://github.com/palantir/tslint ) 。
49+ * ` tsconfig.json ` 包含了工程里TypeScript特定的选项 。
50+ * ` tslint.json ` 保存了要使用的代码检查器的设置 ,[ TSLint] ( https://github.com/palantir/tslint ) 。
5151* ` package.json ` 包含了依赖,还有一些命令的快捷方式,如测试命令,预览命令和发布应用的命令。
5252* ` public ` 包含了静态资源如HTML页面或图片。除了` index.html ` 文件外,其它的文件都可以删除。
53- * ` src ` 包含了TypeScript和CSS源码。` index.tsx ` 是强制的入口文件 。
53+ * ` src ` 包含了TypeScript和CSS源码。` index.tsx ` 是强制使用的入口文件 。
5454
5555# 运行工程
5656
57- 通过如下方式即可简单地运行工程 。
57+ 通过下面的方式即可轻松地运行这个工程 。
5858
5959``` sh
6060npm run start
6161```
6262
63- 它会执行` package.json ` 里面指定的` start ` 命令,并且会启动一个服务器,当我们保存文件时会自动刷新页面 。
64- 通常这个服务器的地址是` http://localhost:3000 ` ,它应该会自动地打开页面 。
63+ 它会执行` package.json ` 里面指定的` start ` 命令,并且会启动一个服务器,当我们保存文件时还会自动刷新页面 。
64+ 通常这个服务器的地址是` http://localhost:3000 ` ,页面应用会被自动地打开 。
6565
66- 它会循环监听方便我们快速地预览改动 。
66+ 它会保持监听以方便我们快速地预览改动 。
6767
6868# 测试工程
6969
@@ -74,15 +74,15 @@ npm run test
7474```
7575
7676这个命令会运行Jest,一个非常好用的测试工具,它会运行所有扩展名是` .test.ts ` 或` .spec.ts ` 的文件。
77- 如同 ` npm run start ` 命令,当检测到有改动的时候Jest会自动地运行。
78- 如果你喜欢的话 ,你还可以同时运行` npm run start ` 和` npm run test ` ,这样你就可以在预览的同时进行测试。
77+ 好比是 ` npm run start ` 命令,当检测到有改动的时候Jest会自动地运行。
78+ 如果喜欢的话 ,你还可以同时运行` npm run start ` 和` npm run test ` ,这样你就可以在预览的同时进行测试。
7979
8080# 生成生产环境的构建版本
8181
82- 在使用` npm run start ` 运行工程的时候,我们并没有生成一个优化的版本 。
83- 通常地,我们想给用户一个运行地尽可能快并在体积上尽可能小的代码 。
82+ 在使用` npm run start ` 运行工程的时候,我们并没有生成一个优化过的版本 。
83+ 通常我们想给用户一个运行的尽可能快并在体积上尽可能小的代码 。
8484像压缩这样的优化方法可以做到这一点,但是总是要耗费更多的时间。
85- 我们把这样的构建版本称做“生产环境”版本(与开发版本想对 )。
85+ 我们把这样的构建版本称做“生产环境”版本(与开发版本相对 )。
8686
8787要执行生产环境的构建,可以运行如下命令:
8888
@@ -98,9 +98,9 @@ npm run build
9898# 创建一个组件
9999
100100下面我们将要创建一个` Hello ` 组件。
101- 这个组件接收任意一个我们想对之打呼呼的名字 (我们把它叫做` name ` ),并且有一个可选数量的感叹号做为结尾(通过` enthusiasmLevel ` )。
101+ 这个组件接收任意一个我们想对之打招呼的名字 (我们把它叫做` name ` ),并且有一个可选数量的感叹号做为结尾(通过` enthusiasmLevel ` )。
102102
103- 当我们这样写 ` <Hello name="Daniel" enthusiasmLevel={3} /> ` ,这个组件会大概渲染成 ` <div>Hello Daniel!!!</div> ` 这样子 。
103+ 若我们这样写 ` <Hello name="Daniel" enthusiasmLevel={3} /> ` ,这个组件大至会渲染成 ` <div>Hello Daniel!!!</div> ` 。
104104如果没指定` enthusiasmLevel ` ,组件将默认显示一个感叹号。
105105若` enthusiasmLevel ` 为` 0 ` 或负值将抛出一个错误。
106106
@@ -139,15 +139,15 @@ function getExclamationMarks(numChars: number) {
139139}
140140```
141141
142- 注意我们定义了一个类型叫做 ` Props ` ,它指定了我们组件要用到的属性。
143- ` name ` 是必需的 ` string ` 类型,且 ` enthusiasmLevel ` 为可选的 ` number ` 类型(你可以通过名字后面加` ? ` 为指定可选参数)。
142+ 注意我们定义了一个类型 ` Props ` ,它指定了我们组件要用到的属性。
143+ ` name ` 是必需的且为 ` string ` 类型,同时 ` enthusiasmLevel ` 是可选的且为 ` number ` 类型(你可以通过名字后面加` ? ` 为指定可选参数)。
144144
145- 我们创建了一个无状态的功能组件( SFC)` Hello ` 。
145+ 我们创建了一个无状态的函数式组件(Stateless Functional Components, SFC)` Hello ` 。
146146具体来讲,` Hello ` 是一个函数,接收一个` Props ` 对象并拆解它。
147- 如果` Props ` 对象里没有设置` enthusiasmLevel ` ,它默认为 ` 1 ` 。
147+ 如果` Props ` 对象里没有设置` enthusiasmLevel ` ,默认值为 ` 1 ` 。
148148
149149使用函数是React中定义组件的[ 两种方式] ( https://facebook.github.io/react/docs/components-and-props.html#functional-and-class-components ) 之一。
150- 如果你喜欢的话,也* 可以* 通过类的方式实现 :
150+ 如果你喜欢的话,也* 可以* 通过类的方式定义 :
151151
152152``` ts
153153class Hello extends React .Component <Props , object > {
@@ -176,7 +176,7 @@ class Hello extends React.Component<Props, object> {
176176
177177现在我们已经写好了组件,让我们仔细看看` index.tsx ` ,把` <App /> ` 替换成` <Hello ... /> ` 。
178178
179- 首先我们在文件顶端导入它 :
179+ 首先我们在文件头部导入它 :
180180
181181``` ts
182182import Hello from ' ./components/Hello.tsx' ;
@@ -195,18 +195,18 @@ ReactDOM.render(
195195
196196这里还有一点要指出,就是最后一行` document.getElementById('root') as HTMLElement ` 。
197197这个语法叫做* 类型断言* ,有时也叫做* 转换* 。
198- 当你比类型检查器更清楚一个表达式的类型的时候,你可以通过这种方式告诉TypeScript 。
198+ 当你比类型检查器更清楚一个表达式的类型的时候,你可以通过这种方式通知TypeScript 。
199199
200200这里,我们之所以这么做是因为` getElementById ` 的返回值类型是` HTMLElement | null ` 。
201- 简单地说,` getElementById ` 返回` null ` 当无法找对对应 ` id ` 元素的时候。
202- 我们假设` getElementById ` 总是成功的,因此我们要使用` as ` 讲法告诉TypeScript这点 。
201+ 简单地说,` getElementById ` 返回` null ` 是当无法找对对应 ` id ` 元素的时候。
202+ 我们假设` getElementById ` 总是成功的,因此我们要使用` as ` 语法告诉TypeScript这点 。
203203
204204TypeScript还有一种感叹号(` ! ` )结尾的语法,它会从前面的表达式里移除` null ` 和` undefined ` 。
205205所以我们也* 可以* 写成` document.getElementById('root')! ` ,但在这里我们想写的更清楚些。
206206
207207# :sunglasses : 添加样式
208208
209- 通过我们的设置为一个组件设置样式很容易 。
209+ 通过我们的设置为一个组件添加样式很容易 。
210210若要设置` Hello ` 组件的样式,我们可以创建这样一个CSS文件` src/components/Hello.css ` 。
211211
212212``` css
@@ -225,15 +225,15 @@ TypeScript还有一种感叹号(`!`)结尾的语法,它会从前面的表
225225}
226226```
227227
228- ` create-react-app ` 利用的工具 (Webpack和一些加载器)允许我们导入样式表文件。
228+ ` create-react-app ` 包含的工具 (Webpack和一些加载器)允许我们导入样式表文件。
229229当我们构建应用的时候,所有导入的` .css ` 文件会被拼接成一个输出文件。
230230因此在` src/components/Hello.tsx ` ,我们需要添加如下导入语句。
231231
232232``` ts
233233import ' ./Hello.css' ;
234234```
235235
236- # 使用Jest书写测试
236+ # 使用Jest编写测试
237237
238238我们对` Hello ` 组件有一些假设。
239239让我们在此重申一下:
@@ -245,24 +245,24 @@ import './Hello.css';
245245我们将针对这些需求为组件写一些注释。
246246
247247但首先,我们要安装Enzyme。
248- [ Enzyme] ( http://airbnb.io/enzyme/ ) 是React生态系统里一个通用工具,它方便了对组件行为书写测试 。
248+ [ Enzyme] ( http://airbnb.io/enzyme/ ) 是React生态系统里一个通用工具,它方便了针对组件的行为编写测试 。
249249默认地,我们的应用包含了一个叫做jsdom的库,它允许我们模拟DOM以及在非浏览器的环境下测试运行时的行为。
250- Enzyme类似,但是是基于jsdom ,并且方便我们查询组件。
250+ Enzyme与此类似,但是是基于jsdom的 ,并且方便我们查询组件。
251251
252- 让我们把它安装为一项开发依赖 。
252+ 让我们把它安装为开发依赖项 。
253253
254254``` sh
255255npm install -D enzyme @types/enzyme react-addons-test-utils
256256```
257257
258258注意我们同时安装了` enzyme ` 和` @types/enzyme ` 。
259- ` enzyme ` 包指的是包含了实际运行地的JavaScript代码的包, ` @types/enzyme ` 包是包含了声明文件 (` .d.ts ` 文件)的包,因此TypeScript能够了解该如何使用Enzyme 。
259+ ` enzyme ` 包指的是包含了实际运行的JavaScript代码包,而 ` @types/enzyme ` 则包含了声明文件 (` .d.ts ` 文件)的包,以便TypeScript能够了解该如何使用Enzyme 。
260260你可以在[ 这里] ( https://www.typescriptlang.org/docs/handbook/declaration-files/consumption.html ) 了解更多关于` @types ` 包的信息。
261261
262- 去们还需要安装 ` react-addons-test-utils ` 。
263- 它是 ` enzyme ` 需要安装的 。
262+ 我们还需要安装 ` react-addons-test-utils ` 。
263+ 它是使用 ` enzyme ` 所需要安装的包 。
264264
265- 现在我们已经设置好了Enzyme,下面开始写测试 !
265+ 现在我们已经设置好了Enzyme,下面开始编写测试 !
266266先创建一个文件` src/components/Hello.test.tsx ` ,与先前的` Hello.tsx ` 文件放在一起。
267267
268268``` ts
@@ -302,41 +302,41 @@ it('throws when the enthusiasm level is negative', () => {
302302
303303这些测试都十分基础,但你可以从中得到启发。
304304
305- # 添加状态管理
305+ # 添加state管理
306306
307- 到此为止,如果你使用React的目的是只获取一次数据并显示,那么你已经达成了 。
308- 但是如果你想开发一个可以交互的应用,那么你需要添加状态管理 。
307+ 到此为止,如果你使用React的目的是只获取一次数据并显示,那么你已经完成了 。
308+ 但是如果你想开发一个可以交互的应用,那么你需要添加state管理 。
309309
310- ## 状态管理概述
310+ ## state管理概述
311311
312- React本身就是一个适合于创建可组合型视图的库存 。
312+ React本身就是一个适合于创建可组合型视图的库 。
313313但是,React并没有任何在应用间同步数据的功能。
314314就React组件而言,数据是通过每个元素上指定的props向子元素传递。
315315
316- 因为React本身并没有提供内置的状态管理功能,React社区先择了Redux和MobX库 。
316+ 因为React本身并没有提供内置的state管理功能,React社区选择了Redux和MobX库 。
317317
318318[ Redux] ( http://redux.js.org ) 依靠一个统一且不可变的数据存储来同步数据,并且更新那里的数据时会触发应用的更新渲染。
319- 状态的更新是以一种不可变的方式进行 ,它会发布一条明确的action消息,这个消息必须被reducer函数处理。
320- 由于使用了这样明确的方式,很容易弄清楚一个action是如何影响程序的状态的 。
319+ state的更新是以一种不可变的方式进行 ,它会发布一条明确的action消息,这个消息必须被reducer函数处理。
320+ 由于使用了这样明确的方式,很容易弄清楚一个action是如何影响程序的state 。
321321
322- [ MobX] ( https://mobx.js.org/ ) 借助于函数式响应型模式,状态被包装在可观察对象里 ,并通过props传递。
323- 通过将状态标记为可观察的即可在所有观察者之间保持状态的同步性 。
322+ [ MobX] ( https://mobx.js.org/ ) 借助于函数式响应型模式,state被包装在了可观察对象里 ,并通过props传递。
323+ 通过将state标记为可观察的,即可在所有观察者之间保持state的同步性 。
324324另一个好处是,这个库已经使用TypeScript实现了。
325325
326326这两者各有优缺点。
327- 通常Redux使用得更广泛 ,因此在这篇教程里,我们主要看如何使用Redux;
328- 但是,你鼓励大家两者都去了解一下 。
327+ 但Redux使用得更广泛 ,因此在这篇教程里,我们主要看如何使用Redux;
328+ 但是也鼓励大家两者都去了解一下 。
329329
330330后面的小节学习曲线比较陡。
331331因此强烈建议大家先去[ 熟悉一下Redux] ( http://redux.js.org/ ) 。
332332
333333## 设置actions
334334
335- 只有当应用里的状态会改变的时候 ,我们才需要去添加Redux。
335+ 只有当应用里的state会改变的时候 ,我们才需要去添加Redux。
336336我们需要一个action的来源,它将触发改变。
337- 这可以是一个定时器或者UI上的一个按钮 。
337+ 它可以是一个定时器或者UI上的一个按钮 。
338338
339- 为此,我们将增加两个按钮来控制` Hello ` 组件的感叹程度 。
339+ 为此,我们将增加两个按钮来控制` Hello ` 组件的感叹级别 。
340340
341341## 安装Redux
342342
@@ -350,7 +350,7 @@ npm install -S redux react-redux @types/react-redux
350350
351351## 定义应用的状态
352352
353- 我们需要定义Redux保存的状态的结构 。
353+ 我们需要定义Redux保存的state的结构 。
354354创建` src/types/index.tsx ` 文件,它保存了类型的定义,我们在整个程序里都可能用到。
355355
356356``` ts
@@ -362,12 +362,12 @@ export interface StoreState {
362362}
363363```
364364
365- 在这里我们想让 ` languageName ` 表示应用使用的编程语言(例如,TypeScript或者JavaScript),` enthusiasmLevel ` 是可变的。
366- 在写我们第一个容器的时候,我们就会明白为什么要令状态与属性稍有不同 。
365+ 这里我们想让 ` languageName ` 表示应用使用的编程语言(例如,TypeScript或者JavaScript),` enthusiasmLevel ` 是可变的。
366+ 在写我们的第一个容器的时候,就会明白为什么要令state与props稍有不同 。
367367
368368## 添加actions
369369
370- 下面我们创建这个应用将要响应的消息类型, ` src/constants/index.tsx ` 。
370+ 下面我们创建这个应用将要响应的消息类型, ` src/constants/index.tsx ` 。
371371
372372``` ts
373373// src/constants/index.tsx
@@ -419,7 +419,7 @@ export function decrementEnthusiasm(): DecrementEnthusiasm {
419419## 添加reducer
420420
421421现在我们可以开始写第一个reducer了!
422- Reducers是函数,它们负责生成应用状态的拷贝使之产生变化 ,但它并没有* 副作用* 。
422+ Reducers是函数,它们负责生成应用state的拷贝使之产生变化 ,但它并没有* 副作用* 。
423423它们是一种* [ 纯函数] ( https://en.wikipedia.org/wiki/Pure_function ) * 。
424424
425425我们的reducer将放在` src/reducers/index.tsx ` 文件里。
@@ -493,7 +493,7 @@ function Hello({ name, enthusiasmLevel = 1, onIncrement, onDecrement }: Props) {
493493```
494494
495495通常情况下,我们应该给` onIncrement ` 和` onDecrement ` 写一些测试,它们是在各自的按钮被点击时调用。
496- 试一试以便掌握书写测试的窍门 。
496+ 试一试以便掌握编写测试的窍门 。
497497
498498现在我们的组件更新好了,可以把它放在一个容器里了。
499499让我们来创建一个文件` src/containers/Hello.tsx ` ,在开始的地方使用下列导入语句。
@@ -635,11 +635,10 @@ create-react-app带有很多很棒的功能。
635635它们的大多数都在我们工程生成的` README.md ` 里面有记录,所以可以简单阅读一下。
636636
637637如果你想学习更多关于Redux的知识,你可以前往[ 官方站点] ( http://redux.js.org/ ) 查看文档。
638- 同样的,[ MobX] ( https://mobx.js.org/ ) 官方问点 。
638+ 同样的,[ MobX] ( https://mobx.js.org/ ) 官方站点 。
639639
640- 如果你想要某个时间点eject,你需要了解再多一些关于Webpack的知识 。
640+ 如果你想要在某个时间点eject,你需要了解再多关于Webpack的知识 。
641641你可以查看[ React & Webpack教程] (./React & Webpack.md)。
642642
643643有时候你需要路由功能。
644644已经有一些解决方案了,但是对于Redux工程来讲[ react-router] ( https://github.com/ReactTraining/react-router ) 是最流行的,并经常与[ react-router-redux] ( https://github.com/reactjs/react-router-redux ) 联合使用。
645- At some point you might need routing.
0 commit comments