Candy 8 lat temu
rodzic
commit
34308141a2
4 zmienionych plików z 136 dodań i 0 usunięć
  1. 2 0
      SUMMARY.md
  2. BIN
      _static/project/count.png
  3. BIN
      _static/project/react.png
  4. 134 0
      project/react/redux.md

+ 2 - 0
SUMMARY.md

@@ -19,6 +19,8 @@
   - DB
     - [MySQL](project/db/mysql.md)
     - [Redis](project/db/redis.md)
+  - React
+    - [React](project/react/redux.md)
 - [运维](operation/README.md)
   - [CI工作流](operation/workflow.md)
   - [重启服务](operation/restarter.md)

BIN
_static/project/count.png


BIN
_static/project/react.png


+ 134 - 0
project/react/redux.md

@@ -0,0 +1,134 @@
+# React and Redux
+
+> view层发出actions通知触发store里的reducer从而来更新state;state的改变会将更新反馈给我们的view层,从而让我们的view层发生相应的反应给用户。
+
+## 流程图
+
+![pic-1](/_static/project/react.png)
+
+## 目录结构
+
+目录结构大概可以这样规划
+
+```
+app
+  |_components
+  |_reducers
+  |_actions
+  |_stores
+    |_configureStores.js
+  |_main.js
+```
+
+## 核心代码
+
+举例核心代码。值得注意的是其中有一个state的传递有一些迷惑的地方,在下面的注释中可以找到思路。
+
+### components
+```js
+import React, { Component } from 'react';
+import { bindActionCreators } from 'redux';
+import { connect } from 'react-redux';
+import * as CounterActions from '../../actions/counter.js';
+
+class Counter extends Component {
+  constructor() {
+    super();
+    this.state = {};
+  }
+  componentWillMount = () => {
+    this.startCount();
+  }
+  startCount = () => {
+    const { actions } = this.props;
+    actions.listen('INC');
+  }
+  render() {
+    return (
+      <div>
+        {this.props.counter.count}
+      </div>
+    );
+  }
+}
+Counter.propTypes = {
+  actions: React.PropTypes.object.isRequired,
+  counter: React.PropTypes.object.isRequired
+};
+// 声明 connect 连接
+// 将 redux 中的 state传给 App
+function mapStateToProps(state) {
+  return {
+    counter: state.counter
+  };
+}
+function mapDispatchToProps(dispatch) {
+  const boundCounter = bindActionCreators(CounterActions, dispatch);
+  return {
+    actions: Object.assign({}, boundCounter)
+  };
+}
+// 声明 connect 连接
+export default connect(mapStateToProps, mapDispatchToProps)(Counter);
+```
+
+### actions
+
+action函数必须返回一个带有type属性的plain object。
+
+```js
+import * as constants from '../../constants/counter';
+export function listen(type) {
+  switch (type) {
+    case 'INC':
+      return {
+        type: constants.INC
+      };
+    case 'DEC':
+      return {
+        type: constants.DEC
+      };
+  }
+}
+```
+
+### reducers
+
+reducer就是迎接action函数返回的线索的数据再处理函数,action是预处理函数。
+
+```js
+import {INC, DEC} from '../../constants/counter';
+// 初始状态
+const initState = {
+  count: 1
+};
+// 定义转换的reducer函数
+// action = {type: 'INC',counter: {count: 1}};
+export default function start(state = initState, action) {
+  switch (action.type) {
+    case INC:
+    // 对这个action做出响应
+      state.count += 1 ; // 改变状态
+      // return {count: 2} 返回给页面;
+      return state;
+    case DEC:
+    // 对这个action做出响应
+      state.count -= 1; // 改变状态
+      // return {count: 0} 返回给页面;
+      return state
+    default:
+      return state;
+  }
+}
+```
+
+```js
+import { combineReducers } from 'redux';
+import counter from './counter'; // {count: 2}返回给页面,所以页面用的是counter.count获取数据2
+// 通过combineReducers将多个reducer合并成一个rootReducer:
+const rootReducer = combineReducers({
+  counter, // {count: 1}
+  others
+});
+export default rootReducer;
+```