Skip to content

Commit

Permalink
完成Reducer学习笔记
Browse files Browse the repository at this point in the history
  • Loading branch information
Kennytian committed Apr 23, 2016
1 parent 4366cdf commit 13a3a95
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 17 deletions.
30 changes: 15 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,34 @@
# React Native 学习旅程
###本文档前置条件
1. 已安装JDK,并配好环境变量。
2. 已安装如下Android SDK,并配好环境变量。
1. 已安装 JDK,并配好环境变量。
2. 已安装如下 Android SDK,并配好环境变量。
- Android SDK Build-tools (23.0.1)
- Android SDK Tools (24.3.3)
- Android SDK Platform-tools (22)
- Android 6.0 (API 23)
- Android Support Library(23.0.1)

推荐从[AndroidDevTools](http://androiddevtools.cn/)下载或者用[腾讯Bugly](http://android-mirror.bugly.qq.com:8080/include/usage.html)镜像加速下载
推荐从[AndroidDevTools](http://androiddevtools.cn/)下载或者用[腾讯Bugly](http://android-mirror.bugly.qq.com:8080/include/usage.html)镜像加速下载

强烈建议配置为``` %ANDROID_HOME%; ``` ``` %ANDROID_HOME%\platform-tools; ``` ``` %ANDROID_HOME%\tools ```形式。

### 安装C++环境
- 下载并安装[Visual C++ 2013](https://www.microsoft.com/zh-cn/download/details.aspx?id=40784)选择vcredist_x64.exe(如果32位系统,下载vcredist_x86.exe),仅有**7M**大小,编译Node.js的C++模块时需要用到。
### 安装 C++ 环境
- 下载并安装[Visual C++ 2013](https://www.microsoft.com/zh-cn/download/details.aspx?id=40784)选择 vcredist_x64.exe(如果32位系统,下载 vcredist_x86.exe),仅有**7M**大小,编译 Node.js 的 C++ 模块时需要用到。

### 安装Python
- 安装[Python 2.7.x](https://www.python.org/downloads/release/python-2711/)(3.x版本不行),安装时确保``` Add python.exe to Path ```已选中状态。
### 安装 Python
- 安装[Python 2.7.x](https://www.python.org/downloads/release/python-2711/)(3.x版本不行),安装时确保 ``` Add python.exe to Path ``` 已选中状态。

### 安装Node.js
### 安装 Node.js
- 从官网下载[Node.js 4.4.x](https://nodejs.org/dist/v4.4.2/node-v4.4.2-x64.msi)的官方4.x版本,``` 不要安装5.x版本 ```,安装时确保``` Add to PATH ```已选中状态。
- 建议设置npm镜像以加速后面的过程(或使用科学上网工具)。
<pre><code>npm config set registry https://registry.npm.taobao.org
npm config set disturl https://npm.taobao.org/dist</code></pre>

### 安装Gradle
### 安装 Gradle
- 虽然在编译Android项目时会自动下载,但如果网络状态不好,很容易下载失败,建议先下载[gradle-2.4-all.zip](http://pan.baidu.com/s/1c0dcgfe)
- 下载上述文件后,将zip文件放在``` C:\Users\kenny\\.gradle\wrapper\dists\gradle-2.4-all\6r4uqcc6ovnq6ac6s0txzcpc0 ``` (不存在的目录就手动创建)。
- 下载上述文件后,将zip文件放在``` C:\Users\kenny\.gradle\wrapper\dists\gradle-2.4-all\6r4uqcc6ovnq6ac6s0txzcpc0 ``` (不存在的目录就手动创建)。

### 安装react-native命令行工具
### 安装 react-native 命令行工具
<pre><code>npm install -g react-native-cli</code></pre>
请耐心等待1-3分钟。

Expand All @@ -39,7 +39,7 @@ npm config set disturl https://npm.taobao.org/dist</code></pre>

请耐心等待5-10分钟。

### 运行React Native
### 运行 React Native
进入RNProject目录, 在命令行里执行

<pre><code>react-native run-android</code></pre>
Expand All @@ -51,12 +51,12 @@ npm config set disturl https://npm.taobao.org/dist</code></pre>

<pre><code>adb reverse tcp:8081 tcp:8081</code></pre>

建议使用Android 5.0系统手机,不用手动设置Debug server host,但是最低要求Android 4.1系统手机
建议使用 Android 5.0 系统手机,不用手动设置 Debug server host ,但是最低要求 Android 4.1 系统手机

提示:如果你执行``` adb devices ```没有问题,但执行上面``` adb reverse ```命令出问题,请下载 [utility/adb.zip](https://raw.githubusercontent.com/Kennytian/learning-react-native/master/utility/adb.zip) ,解压后,将3个文件放在``` %ANDROID_HOME%\platform-tools ```
提示:如果你执行``` adb devices ```没有问题,但执行上面``` adb reverse ```命令出问题,请下载 [utility/adb.zip](https://raw.githubusercontent.com/Kennytian/learning-react-native/master/utility/adb.zip) 关解压,将3个文件放在``` %ANDROID_HOME%\platform-tools ```

### 开发
用IDE打开RNProject目录, 开始开发吧!
用 IDE 打开 RNProject 目录,开始开发吧!

### 反馈
- QQ:2225226
Expand Down
105 changes: 103 additions & 2 deletions redux/reducer.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ Action只描述了**有事情发生了**这一事实,而reducer要做的事就

通常,这个state树还需要存放其它一些UI数据,但尽量把这些数据与UI相关的state分开。

<pre><code>{
<pre><code>
{
visibilityFilter: 'SHOW_ALL',
hotels:[
{
Expand All @@ -22,14 +23,114 @@ Action只描述了**有事情发生了**这一事实,而reducer要做的事就
text: '客栈',
isShow: false
}]
}</code></pre>
}
</code></pre>

> ### 处理 Reducer 关系时的注意事项
> 开发复杂的应用时,不可避免会有一些数据相互引用。建议你尽可能地把 state 范式化,不存在嵌套。
> 把有数据放到一个对象里,每个数据以 ID 为主键,不同数据相互引用时通过 ID 来查找。
> 把应用的 state 想像成数据库。
> 例如,实际开发中,在 state 里同时存放 `hotelsById: { id -> hotel } 和 hotels: array<id>` 是比较好的方式。
## 处理单个 Action
reducer就是一个函数,接收旧的state和action,返回新的state.

`(previousState,action) => newState`

之所以称作reducer是因为它将被传递给`Array.prototype.reduce(reducer,?initialValue)`方法。保持reducer纯净是非常重要的,**永远不要在reducer里做这些操作**:
* 修改传入参数
* 执行API请求和路由跳转等
* 调用非纯属函数,如Date.now()等

只需要谨记reducer一定要保持纯净,**只要传入参数一样,返回必须一样。没有特殊情况,没有副作用,没有API请求、没有修改参数、单纯执行计算**

<pre><code>
function hotelApp(state = initialState, action) {
// 这里暂不处理任何 action,
// 仅返回传入的 state。
return state;
}
</code></pre>

现在可以处理SET_VISIBILITY_FILTER, 需要做的只是改变state中的visibilityFilter.
<pre><code>
function hotelApp(state = initialState, action) {
switch(action.type) {
case SET_VISIBILITY_FILTER:
return Object.assign({}, state, {
visibilityFilter: action.filter
});
default:
return state;
}
}
</code></pre>

注意:
1. **不要修改state**, 使用 [Object.assign()](https://cnodejs.org/topic/56c49662db16d3343df34b13) 新建一个副本( `assign() 可以快速的复制一个或者多个对象到目标对象中` ). 不能`Object.assign(state, {visibilityFilter: action.filter})`, 因为它会改变第一个参数的值, **必须把第一个参数设置为空对象**, 即: `Object.assign({}, {visibilityFilter: action.filter})`
2. 在 default 情况下返回旧的 state. 遇到未知的 action时, 一定要返回旧的state.

## 处理多个Action
还有两个action需要处理, 我们先处理`ADD_HOTEL`.
<pre><code>
function hotelApp(state = initialState, action) {
switch(action.type) {
case SET_VISIBILITY_FILTER:
return Object.assign({}, state, {
visibilityFilter: action.filter,
});
case ADD_HOTEL:
return Object.assign({}, state, {
text: action.text,
isShow: false
});
default:
return state;
}
}
</code></pre>

COMPLETE_TODO 也很好理解:
<pre><code>
case COMPLETE_TODO:
return Object.assign({}, state, {
todos: [
...state.todos.slice(0, action.index), //比如: 0 ~ 5
Object.assign({}, state.todos[action.index], { //此处为6
completed: true
}),
...state.todos.slice(action.index + 1) //后面就是7
]
});
</code></pre>
我们不能直接修改却要更新数组中指定的一项数据,要先把**前面****后面**都切开。**时刻谨记永远不要在克隆 state 前修改它**

combineReducers 接收一个对象, 可以把所有顶级的reducer 放到一个独立的文件中, 通过 export 暴露出每个 reducer 函数,然后使用 import * as reducer 得到一个以它们名字作为 key 的 object:
<pre><code>
import { combineReducers } from 'redux';
import * as reducers from './reducers';

const hotelApp = combineReducers(reducers);
</code></pre>

### 知识补充:
<pre><code>
var o1 = { a: 1 };
var o2 = { b: 2 };
var o3 = { c: 3 };

var obj = Object.assign(o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3 }
console.log(o1); // { a: 1, b: 2, c: 3 }, target object itself is changed.
</code></pre>

<pre><code>
var str="Hello happy world!"
str.slice(6); //happy world!

var str="Hello happy world!"
str.slice(6, 11) //happy
</code></pre>


### 相关文档
Expand Down

0 comments on commit 13a3a95

Please sign in to comment.