Skip to content

Commit 53babc5

Browse files
committed
Merge branch 'BerlinChan-master'
2 parents d0bad38 + 432906b commit 53babc5

File tree

7 files changed

+103
-121
lines changed

7 files changed

+103
-121
lines changed

11_src/src/action-creators.js

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,34 @@
1-
// Tutorial 12 - Provider-and-connect.js
1+
// 章节 12 - Provider-and-connect.js
22

3-
// We're using Bluebird (https://github.com/petkaantonov/bluebird) as promise library but you could really
4-
// use any promise lib you want.
3+
// 我们使用 Bluebird(https://github.com/petkaantonov/bluebird) 作为 promise 库,但其实你可以用任何你喜欢的。
54
import Promise from 'bluebird'
65

7-
// Our action creator just gets the current time in a delayed fashion to illustrate the use of the promise
8-
// middleware.
6+
// 我们的 action 创建函数在一段延迟后获取当前时间,用于演示 promise 中间件的用法。
97

10-
// The promise middleware works by waiting for either:
11-
// 1) an action with this format:
8+
// promise 中间件接收2种情况的 action:
9+
// 1) 一个如下格式的 action:
1210
// {
13-
// types: [REQUEST, SUCCESS, FAILURE], // actions types given in this specific order
11+
// types: [REQUEST, SUCCESS, FAILURE], // action 的 types 需要按该顺序给出
1412
// promise: function() {
15-
// // return a promise
13+
// // 返回一个 promise
1614
// }
1715
// }
18-
// 2) or anything else what would be passed to the next middleware or to Redux (actually, with this
19-
// implementation of the promise middleware, the "anything else" has to NOT contain a promise
20-
// property to be passed to the next middleware or Redux)
16+
// 2) 其他任何可以传递给下一个中间件或 Redux 的 action, (准确的说,在这个 promise 中间件的实现中,这里的"其他任何 action" 传递到下一个中间件或 Redux 时,必须不包含 promise 属性)
2117

22-
// When the promise middleware receives this action, it will create 2 actions from this one:
23-
// 1 action for the REQUEST and later 1 action for the SUCCESS or the FAILURE of the action creator.
18+
// 当该 promise 中间件接收到 action 之后,它会生成2个 action:
19+
// 一个 action 用于 action 创建函数的 REQUEST 情况,
20+
// 后一个 action 用于 action 创建函数的 SUCCESS 或 FAILURE 情况
2421

25-
// Again, the code for the promise middleware is not complicated and it is worth having a look
26-
// at it (./promise-middleware.js)
22+
// 再者,这个 promise 中间件的代码并不复杂,值得去看一看 (./promise-middleware.js)
2723

28-
// The action is delayed by "delay" ms passed as a parameter of the action creator. Try to change
29-
// this value to verify that the delay correctly impacts our UI.
24+
// 下面的 action 使用 "delay" 作为一个参数传递,用来延迟该 action 创建函数。
25+
// 尝试改变延迟的值,验证它是否正确影响了我们 UI。
3026
export function getTime(delay) {
3127
return {
3228
types: ['GET_TIME_REQUEST', 'GET_TIME_SUCCESS', 'GET_TIME_FAILURE'],
3329
promise: () => {
3430
return new Promise((resolve, reject) => {
35-
// Just simulating an async request to a server via a setTimeout
31+
// 通过 setTimeout 来模拟一个异步服务器请求
3632
setTimeout(() => {
3733
const d = new Date()
3834
const ms = ('000' + d.getMilliseconds()).slice(-3)

11_src/src/application.jsx

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
// Tutorial 12 - Provider-and-connect.js
1+
// 章节 12 - Provider-and-connect.js
22

3-
// Now is the time to meet the first binding that redux-react (https://github.com/rackt/react-redux)
4-
// brings to us: the Provider component.
3+
// 现在是时候见识 redux-react(https://github.com/rackt/react-redux)
4+
// 如何在 Provider 组件中为我们做初次绑定了。
55

6-
// Provider is a React Component designed to be used as a wrapper of your application's root component. Its
7-
// purpose is to provide your redux instance to all of your application's components. How it does that does not
8-
// really matter to us but just to let you know, it's using React's context feature (it's undocumented so you
9-
// don't have to know about it, but if you're curious:
10-
// https://www.tildedave.com/2014/11/15/introduction-to-contexts-in-react-js.html).
6+
// Provider 是一个 React 组件,它被设计用作于包裹你应用的根组件。
7+
// 它的目的是提供你的 Redux 实例给所有应用中的组件。
8+
// 我们不太关心它是如何做到的,你只需知道: 它用了 React 的上下文功能(context feature),
9+
// 它没有说明文档所已不必在意它,但你实在是好奇的话可以参考: https://www.tildedave.com/2014/11/15/introduction-to-contexts-in-react-js.html
1110

1211
import React from 'react'
1312
import Home from './home'
@@ -16,15 +15,14 @@ import { Provider } from 'react-redux'
1615
export default class Application extends React.Component {
1716
render () {
1817
return (
19-
// As explained above, the Provider must wrap your application's Root component. This way,
20-
// this component and all of its children (even deeply nested ones) will have access to your
21-
// Redux store. Of course, to allow Provider to do that, you must give it the store
22-
// you built previously (via a "store" props).
18+
// 正如上面介绍的,Provider 必须包裹你的应用程序根组件。
19+
// 如此以来,该组件以及它的子元素(甚至更深的后代)就能访问你的 Redux store。
20+
// 当然,为了允许 Provider 这么做,你必须通过名为 "store" 的 props 将 store 传递给它。
2321
<Provider store={ this.props.store }>
2422
<Home />
2523
</Provider>
2624
)
2725
}
2826
}
2927

30-
// Go to ./home.jsx to discover how you could read from state and dispatch an action from a React component.
28+
// 转到 ./home.jsx,从这个React组件中,去发现更多关于 state 和派发 action 的细节。

11_src/src/create-store.js

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,28 @@
1-
// Tutorial 12 - Provider-and-connect.js
1+
// 章节 12 - Provider-and-connect.js
22

3-
// There is not much to say here, you've seen this plenty of times and it should feel pretty
4-
// familiar to you now...
3+
// 这里没有很多要说的, 现在你已经看到过这些很多次, 而且应该对它们很熟悉了...
54

6-
// One thing to notice though: we're not using the thunk middleware that we've seen before. Instead
7-
// we use a promise middleware solution that will allow us to handle asynchronous action creators and
8-
// to do some nice real time updates on our UI (could also do some optimistic updates).
9-
// This middleware was discussed here: https://github.com/rackt/redux/issues/99 and it is used
10-
// in this very good react-redux-universal-example: https://github.com/erikras/react-redux-universal-hot-example
11-
// that I strongly suggest you get a look at (later, not right now ;)).
5+
// 尽管这样,但还是有一点要注意: 我们这里不使用之前用过的 thunk middleware
6+
// 替而代之的是 promise middleware,它允许我们处理异步的 action 创建函数,
7+
// 然后漂亮的实时处理UI更新(也可以做一些乐观的更新)。
8+
// 这个中间件在 https://github.com/rackt/redux/issues/99有讨论,
9+
// react-redux-universal-example: https://github.com/erikras/react-redux-universal-hot-example中有非常好的使用案例,
10+
// 我强烈推荐你去看一看(之后不是现在;))
1211

1312
import { createStore, applyMiddleware, combineReducers } from 'redux'
14-
// You can go and see the code for this middleware, it's not very complicated and makes a good
15-
// exercise to sharpen your understanding on middlewares.
13+
// 你可以去看一看这个中间件,它不是很复杂,而且能帮你锻炼出对中间件更敏锐的理解。
1614
import promiseMiddleware from './promise-middleware'
17-
// We'll just have one reducer in this application but the ES6 import notation below is
18-
// pretty interesting to import and produce a reducers hash in one go. Have a look in
19-
// ./reducers.js to see what our reducer actually do (no magic there).
15+
16+
// 在本应用中我们仅有一个 reducer,
17+
// 但是下面用 ES6 写的 import,有趣且一气呵成的导入并生成了多个 reducer。
18+
// 去 ./reducers.js 看看我们的 reducer 究竟是怎么做的(这里没有魔法)。
2019
import * as reducers from './reducers'
2120

22-
// The data parameter that we see here is used to initialize our redux store with data. We didn't
23-
// talk about this yet for simplicity but thanks to it your reducers can be initialized
24-
// with real data if you already have some. For example in an isomorphic/universal app where you
25-
// fetch data server-side, serialize and pass it to the client, your Redux store can be
26-
// initialized with that data.
27-
// We're not passing any data here but it's good to know about this createStore's ability.
21+
// 这里看到的 data 参数是用于初始化 Redux store。
22+
// 为简单起见我们不讨论它,但要感谢它让你在有真实数据的情况下来初始化 reducer。
23+
// 例如在一个同构/通用应用中,你能从服务器端拉取数据,然后序列化并传递到客户端,
24+
// 你的 Redux store 就能用这些数据来初始化。
25+
// 这里我们没传任何数据,但最好要知道这个 createStore 是做什么的
2826
export default function(data) {
2927
var reducer = combineReducers(reducers)
3028
var finalCreateStore = applyMiddleware(promiseMiddleware)(createStore)
@@ -33,4 +31,4 @@ export default function(data) {
3331
return store
3432
}
3533

36-
// Go to ./application.jsx to learn of the first Redux binding for React: the Provider component.
34+
// 转到 ./application.jsx,去学习使用 Provider 组件首次将 Redux 绑定到 React

11_src/src/home.jsx

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@
1111
// React-Redux 为我们暴露了一个组件中的函数让我们可以使用。
1212

1313
// 这个函数就是 Connect , 它让我们可以实现一个组件和 Redux store 的绑定,
14-
// 通过这种绑定可以让store通过组件的属性 (prop) 分发函数,
14+
// 通过这种绑定可以让store通过组件的属性 (prop) 分发函数,
1515
// 也可以根据我们自己的需要增加任何需要暴露的属性作为store里面state的一部分。
1616

17-
// 使用了 Connect , 你可以通过添加很少的代码让一个组件变得更"聪明",
17+
// 使用了 Connect , 你可以通过添加很少的代码让一个组件变得更"聪明",
1818
// (https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0).
1919

2020
// Connect 是一个接受一些映射函数作为参数, 并返回一个你想要链接的组件类函数, 的函数.
@@ -27,13 +27,14 @@
2727
// - http://natpryce.com/articles/000814.html
2828

2929
// Connect "HOC" 主要被设计用于解决无论简单和困难的使用场景。
30-
// 在现有的例子中, 我们不会使用 Connect 最复杂的形式,
31-
// 但是你可以在完整的 API 文档中找到有关的全部信息:
30+
// 在现有的例子中, 我们不会使用 Connect 最复杂的形式,
31+
// 但是你可以在完整的 API 文档中找到有关的全部信息:
3232
// https://github.com/rackt/react-redux/blob/v4.0.0/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options
3333

3434
// 以下是完整的 Connect 特征:
3535
// connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])
3636
// 它的使用方法如下:
37+
3738
/*
3839
const wrappedComponentClass = connect(...)(ComponentClass)
3940
*/
@@ -44,7 +45,7 @@
4445
// 这个函数我们一般称它为 Selector。
4546
// 它需要接受两个参数: 当前 store 的状态 (state) 以及当前组件的 prop。
4647
// 可以看见我们将这个函数命名为 "mapStateToProps",
47-
// 这个名字从字面意义上告诉我们它的作用:
48+
// 这个名字从字面意义上告诉我们它的作用:
4849
// 它创造了从 state 到一些组件 props 的映射 (map)
4950

5051
// 为了完成提取部分组建的 props 作为 state 的动作, (Ex: state.items[props.someID]).
@@ -54,23 +55,24 @@
5455

5556
import React from 'react'
5657
import { connect } from 'react-redux'
57-
// 我们会使用一些 ES6 中的 import 技巧来得到所有的 action creator 并生成一个哈希值,
58+
// 我们会使用一些 ES6 中的 import 技巧来得到所有的 action creator 并生成一个哈希值,
5859
// 就跟我们当时在 reducer 部分所做的一样。如果你还没有了解action creator的话, 去看看相关章节吧~ (./action-creators.js).
60+
5961
import * as actionCreators from './action-creators'
6062

6163
class Home extends React.Component {
6264
onTimeButtonClick (delay) {
6365
// 这个按钮处理器在用户的点击事件后会分发一个 action。
6466
// 我们在这里会使用一个 Connect 提供的分发函数,
65-
// 也有很多其他的调用被绑定到分发器的 actionCreator 的方式,
67+
// 也有很多其他的调用被绑定到分发器的 actionCreator 的方式,
6668
// 这种方式提供了第二个 Connect 的参数:
6769
// https://github.com/rackt/react-redux/blob/v4.0.0/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options
6870
// 被传到 actionCreators.getTime 的 delay 值是为了在我们能得到当前时间之前模拟异步的工作,
6971
// 试着修改这个值来正确影响我们的 UI
7072
this.props.dispatch(actionCreators.getTime(delay))
7173
}
7274
render () {
73-
75+
7476
// 因为 Connect 我们能够通过 props 取到特定的数据
7577
var { frozen, time, reduxState } = this.props
7678
var attrs = {}
@@ -94,7 +96,7 @@ class Home extends React.Component {
9496
Try to change this value (in <b>src/home.jsx - line 95</b>) to verify that the delay given correctly impacts our UI.
9597
</i>
9698
<br />
97-
{/* 我们在这里定义我们的点击处理器 */}
99+
{/* 这里注册按钮的 "onClick" 句柄: */}
98100
<button { ...attrs } onClick={() => this.onTimeButtonClick(DELAY)}>Get time!</button>
99101
<pre>
100102
redux state = { JSON.stringify(reduxState, null, 2) }
@@ -109,7 +111,7 @@ const mapStateToProps = (state/*, props*/) => {
109111
return {
110112
frozen: state._time.frozen,
111113
time: state._time.time,
112-
// 像(reduxState: state) 这样提供整个 state 是一种不好的实现,
114+
// 像 (reduxState: state) 这样提供整个 state 是一种不好的实现,
113115
// 我们在这里这样写是为了让大家能看到我们页面字符串化的结果。更多信息请访问以下链接:
114116
// https://github.com/rackt/react-redux/blob/v4.0.0/docs/api.md#inject-dispatch-and-every-field-in-the-global-state
115117
reduxState: state,
@@ -123,19 +125,19 @@ export default ConnectedHome
123125
// 也许你会发现因为 Redux 让我们可以拥有需要一些状态 (比如保存当前时间) 的动态组件,
124126
// 而这个状态并不在组件当中存在,
125127
// 我们的组件只会接受含有需要的数据的 prop。
126-
// 我们现在拥有了一个无状态组件 (stateless component), 相比较有状态的组件,
128+
// 我们现在拥有了一个无状态组件 (stateless component), 相比较有状态的组件,
127129
// 我们在编码中应该尽可能更多的使用无状态组件, 因为它们更易于被复用。
128130
// 正如在 "onTimeButtonClick" 处理器中建议的一样, 我们甚至可以把点击的回调函数作为一个 prop
129131
// 从 Connect 的第二个参数 "mapDispatchToProps" 中传入。这么做的话, 我们就可以在组件之外获得按钮的行为,
130132
// 通过允许另一种点击行为让我们更易于重用这个按钮。
131133
// 可复用性的概念也许看起来被过度强调了, 但是拥有一个可复用的组件通常也意味着
132134
// 这个组件能够很简单的被测试 (因为你可以将任何你想要的数据和处理器插入你的组件中,
133-
// 从而很简单的保证它的正确运行)
135+
// 从而很简单的保证它的正确运行)
134136

135137
// 在去看 ./12_final-words.js 之前, 请仔细看以下另一种使用 Connect HOC 的方法。
136138

137139
// 因为 Connect 返回了一个接受一个 class 并返回另一个 class 的函数,
138-
// 我们可以用它作为 ES7 的 decorator。Decorator 是一种 ES7 的实验新特性,
140+
// 我们可以用它作为 ES7 的 decorator。Decorator 是一种 ES7 的实验新特性,
139141
// 让我们能够在设计的时候注释和修改 class 和属性 (https://github.com/wycats/javascript-decorators).
140142

141143
// 作为一个试验中的特性, 也许会有变化或问题。
@@ -154,20 +156,20 @@ export default ConnectedHome
154156
export default class MyClass {}
155157
*/
156158

157-
// 通过这种特性使用redux connect, 我们可以把如下代码:
159+
// 通过这种特性使用 redux connect, 我们可以把如下代码:
158160

159161
/*
160-
let mapStateToProps = (state) => { ... }
161-
class MyClass {}
162-
export default connect(mapStateToProps)(MyClass)
163-
*/
162+
let mapStateToProps = (state) => { ... }
163+
@connect(mapStateToProps)
164+
export default class MyClass {}
165+
*/
164166

165167
// 替换成:
166168

167169
/*
168170
let mapStateToProps = (state) => { ... }
169-
@connect(mapStateToProps)
170-
export default class MyClass {}
171+
class MyClass {}
172+
export default connect(mapStateToProps)(MyClass)
171173
*/
172174

173175
// 正如我们看到的, 高层组件的函数现在被作为隐函数使用 ( @connect(mapStateToProps) )

11_src/src/index.jsx

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,22 @@
1-
// Tutorial 12 - Provider-and-connect.js
1+
// 章节 12 - Provider-and-connect.js
22

3-
// This file is the entry point of our JS bundle. It's here that we'll create our Redux store,
4-
// instantiate our React Application root component and attach it to the DOM.
3+
// 这个文件是我们 JS 包的入口。 在这里将创建我们的 Redux store,实例化我们的 React 应用根组件然后将它附加到DOM中。
54

65
import React from 'react'
76
import { render } from 'react-dom'
8-
// All store creation specific code is located in ./create-store.js
7+
// 所有创建 store 的具体代码在 ./create-store.js
98
import createStore from './create-store'
10-
// Application is the root component of our application and the one that holds Redux's Provider...
9+
// Application 是我们应用的根组件,它包含了 Redux Provider...
1110
import Application from './application'
1211

13-
// Just as we did so many times in previous examples, we need to create our redux instance. This time
14-
// all code for that task was moved to a specific module that returns a single function to trigger the
15-
// instantiation.
12+
// 就像以前的很多例子一样,我们需要创建 Redux 实例。 这次所有的代码被移到专门的模块中(译者注: create-store.js),并返回一个函数来触发实例化。
1613
const store = createStore()
1714

18-
// Now, time to render our application to the DOM using ReactDOM.render (or just render thanks to
19-
// the ES6 notation: import { render } from 'react-dom')...
15+
// 现在,是时候使用 ReactDOM.render(或者仅仅用 render,这要感谢 ES6 的解构赋值写法: import { render } from 'react-dom')渲染我们的应用到 DOM 中
2016
render(
21-
// ... and to provide our Redux store to our Root component as a prop so that Redux
22-
// Provider can do its job.
23-
<Application store={store} />,
24-
document.getElementById('app-wrapper')
17+
// ... 接着将我们的 Redux store 作为 props 提供给根组件,于是 Redux Provider 可以做它该做的事情。
18+
<Application store={store} />,
19+
document.getElementById('app-wrapper')
2520
)
2621

27-
// Go to ./create-store.js to review what you know now perfectly: "How to create a Redux store?"
22+
// 转到 ./create-store.js 去浏览你已深知的一点: "如何创建一个 Redux store?"

0 commit comments

Comments
 (0)