基础

  • Array.prototype.reduce
//类似的核心思想
const initState = '';
const actions = ['a', 'b', 'c'];
const newState = actions.reduce(
( (prevState, action) => prevState + action ),
initState
); //action: actions;
//state: initState,newState;
//reducer: (prevState, action) => prevState + action //计算

Action

  • 描述有什么事情发生了;
{
type: 'ADD_TODO',
text: 'Build Redux app'
}
  • 改变State只能通过actions, 使用store.dispatch()。并且,每一个action都必须是Javascript Plain Object;
  • 为保证状态保存、回放、Undo 之类的功能可以被实现, action必须是可以被序列化的因此,不能包含如函数调用这样的不可序列化字段;
  • type是必须要有的字符串属性; 建议文档;
  • 好的结构中应该每次action传需要的数据而不是整个
{
type: SET_VISIBILITY_FILTER,
filter: SHOW_COMPLETED
}

Action Creator

  • 事实上,创建action对象更多地是通过一个创建函数;
function addTodo(text) {
return {
type: ADD_TODO,
text
};
}
//触发
dispatch(addTodo(text));
  • dispatch可以直接来自store.dispatch;
handleClick() {
// Works! (but you need to grab store somehow)
store.dispatch(addTodo('Fix the issue'));
}`
  • react-redux中可以通过connect(mapStateToProps,mapDispatchToProps)(Counter);

    • mapStateToProps函数通过返回一个映射对象selector,指定了 Store/State属性映射到React Componentthis.props的情况;
class AddTodo extends Component {
handleClick() {
// Works!
this.props.dispatch(addTodo('Fix the issue'));
}
....
} //将dispatch和state放入props
export default connect(select)(AddTodo);
  • 或者结合bindActionCreators(actionCreators, dispatch);
import * as CounterActions from '../actions/counter';

function mapStateToProps(state) {
return {
counter: state.counter
};
} function mapDispatchToProps(dispatch) {
return bindActionCreators(CounterActions, dispatch);
} export default connect(mapStateToProps, mapDispatchToProps)(Counter); //可以直接添加actionCreators //调用
<button onClick={this.props.addTodo}/>add</button>

Reducers

  • 描述事情发生后state如何改变;

更新成员

  • 为了确保State的消费者在判断数据是否变化时,只要简单地进行引用比较避免Deep Equal的遍历,需要确保State中每个节点都是不可改变的;

  • Reducer中更新State成员需要

  • 增加

//对象
let counters = {
faves: 0,
forward: 20,
}
// this creates a brand new copy overwriting just that key
counters = {...counters, faves: counters.faves + 1} //数组; 调换顺序,可以改变增加的位置; let todos = [
{ id: 1, text: 'have lunch'}
]
todos = [...todos, { id: 2, text: 'buy a cup of coffee'} ]
  • 删除
//数组
let users = [...];
users = users.filter(user=> user.id !== find.id)
  • 由于更新数据的差异:如对于数组型react:state操作后,会同时更新操作位置之后的数据;而redux则只会更新操作位置的数据;

同步执行

  • Reducer的执行是同步的;
  • 在给定initState以及一系列的actions,都应该得到相同的newState;

分割reduce

  • Reduceraction.type是多对多的关系;
export default function counter(state = 0, action) {
switch (action.type) {
case INCREMENT_COUNTER:
return state + 1;
case DECREMENT_COUNTER:
return state - 1;
default:
return state;
}
}
  • 在程序变多时可以使用combineReducers({field1: reducerForField1,....})来管理

    • 每个reducerForField1将仅仅获得State.field1的值,而看不到State下的其他字段的内容;
    • 响应的返回结果也会被合并到对应的State字段中;
import { combineReducers } from 'redux';

const todoAppReducer = combineReducers({
visibilityFilter: visibilityFilterReducer
todos: todosReducer
}); //
visibilityFilterReducer 仅仅负责处理 State.visibilityFilter 字段的状态
  • 注意使用combineReducers的前提是,每一个被组合的Reducer仅仅和State的一部分数据相关;
  • 如果需要消费其他State字段,那还是需要在大switch中为特定处理函数传入整个State;
function todoAppReducer(state = initialState, action) {
switch (action.type) {
case FAVE_ALL_ITEMS:
return Object.assign({}, state, faveThemAll(state));
default:
return state;
}
}

Store

  • 维护应用程序状态的对象;
  • 构造Store对象,仅需要提供一个Reducer函数;
import { combineReducers, createStore } from 'redux';
import * as reducers from './reducers'; const todoAppReducer = combineReducers(reducers);
const store = createStore(todoAppReducer); // Line 5 store.dispatch({type: 'ADD_TODO', text: 'Build Redux app'});
  • 可以在createStore的时候为Store指定一个初始状态;
const store = createStore(reducers, window.STATE_FROM_SERVER);

方法

  • store.getState(): 获取最近的内部状态对象;
  • store.dispatch(action): 将一个action对象发送给reducer;
  • store.subscribe(listener):订阅状态的变化;并不推荐使用, 可以搭配Observable模式的程序,react中不建议;

Provider Component

  • 通过Provider Component来设定connect从哪里获得store对象;
React.render(
<Provider store={store}>
{() => <MyRootComponent />} //react 0.14: <MyRootComponent />
</Provider>,
rootEl
);

主要流程

  • 设置redecers,分片的话使用redux: combineReducers;
  • 创建store,使用redux: createStore,传入reducers;
  • 在特定的组件/顶层组件绑定状态和dispatch,使用react-redux: connet,传入状态映射selector;
  • store关联到绑定后的特定/顶层组件,使用react-resuc: Provider;
  • 设置actions,并在组件想要调用的地方触发this.props.dispatch(),自动更新state;

其他

  • 在绑定组件时使用redux: bindActionCreators,connect传入第二参数,直接将dispatch(actions)传入组件ptops; //注意此时action则必须是Action Creator;
  • 在创建store时使用redux: applyMiddleware先传入中间件,再创建
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import reducer from '../reducers'; const createStoreWithMiddleware = applyMiddleware(
thunk
)(createStore); export default function configureStore(initialState) {
const store = createStoreWithMiddleware(reducer, initialState);
return store;
}
//
const store = configureStore();

react-redux(1)的更多相关文章

  1. webpack+react+redux+es6开发模式

    一.预备知识 node, npm, react, redux, es6, webpack 二.学习资源 ECMAScript 6入门 React和Redux的连接react-redux Redux 入 ...

  2. react+redux教程(六)redux服务端渲染流程

    今天,我们要讲解的是react+redux服务端渲染.个人认为,react击败angular的真正“杀手锏”就是服务端渲染.我们为什么要实现服务端渲染,主要是为了SEO. 例子 例子仍然是官方的计数器 ...

  3. react+redux教程(五)异步、单一state树结构、componentWillReceiveProps

    今天,我们要讲解的是异步.单一state树结构.componentWillReceiveProps这三个知识点. 例子 这个例子是官方的例子,主要是从Reddit中请求新闻列表来显示,可以切换reac ...

  4. react+redux官方实例TODO从最简单的入门(6)-- 完结

    通过实现了增-->删-->改-->查,对react结合redux的机制差不多已经了解,那么把剩下的功能一起完成吧 全选 1.声明状态,这个是全选状态 2.action约定 3.red ...

  5. react+redux官方实例TODO从最简单的入门(1)-- 前言

    刚进公司的时候,一点react不会,有一个需求要改,重构页面!!!完全懵逼,一点不知道怎么办!然后就去官方文档,花了一周时间,就纯react实现了页面重构,总体来说,react还是比较简单的,由于当初 ...

  6. 重写官方TodoList,对于初学react+redux的人来说,很有好处

    虽然官网的TodoList的例子写的很详细,但是都是一步到位,就是给你一个action,好家伙,全部都写好了,给你一个reducer,所有功能也是都写好了,但是我们这些小白怎么可能一下就消化那么多,那 ...

  7. react+redux教程(四)undo、devtools、router

    上节课,我们介绍了一些es6的新语法:react+redux教程(三)reduce().filter().map().some().every()....展开属性 今天我们通过解读redux-undo ...

  8. react+redux教程(三)reduce()、filter()、map()、some()、every()、...展开属性

    reduce().filter().map().some().every()....展开属性   这些概念属于es5.es6中的语法,跟react+redux并没有什么联系,我们直接在https:// ...

  9. react+redux教程(二)redux的单一状态树完全替代了react的状态机?

    上篇react+redux教程,我们讲解了官方计数器的代码实现,react+redux教程(一).我们发现我们没有用到react组件本身的state,而是通过props来导入数据和操作的. 我们知道r ...

  10. react+redux教程(一)connect、applyMiddleware、thunk、webpackHotMiddleware

    今天,我们通过解读官方示例代码(counter)的方式来学习react+redux. 例子 这个例子是官方的例子,计数器程序.前两个按钮是加减,第三个是如果当前数字是奇数则加一,第四个按钮是异步加一( ...

随机推荐

  1. ClassLoad的加载过程及分析

    -Xbootclasspath:bootclasspath 让jvm从指定路径(可以是分号分隔的目录.jar.或者zip)中加载bootclass,用来替换jdk的rt.jar:若非必要,一般不会用到 ...

  2. 20145213《Java程序设计》第一周学习总结

    20145213<Java程序设计>第一周学习总结 教材学习内容总结 期待了一个寒假,终于见识到了神秘的娄老师和他的Java课.虽说算不上金风玉露一相逢,没有胜却人间无数也是情理之中,但娄 ...

  3. 浅析 Cordova for iOS

    转自@夏小BO的技术博客: Cordova,对这个名字大家可能比较陌生,大家肯定听过 PhoneGap 这个名字,Cordova 就是 PhoneGap 被 Adobe 收购后所改的名字.(Cordo ...

  4. 大数计算_BigNum优化_加减乘除乘方取余_带注释_数组

    #include <iostream> #include <algorithm> #include <cstring> #include <cstdlib&g ...

  5. 比较 http连接 vs socket连接

    http连接 :短连接,客户端,服务器三次握手建立连接,服务器响应返回信息,连接关闭,一次性的socket连接:长连接,客户端,服务器三次握手建立连接不中断(通过ip地址端口号定位进程)及时通讯,客户 ...

  6. DB2 SQL Mixed data in character strings

    Mixed character data and graphic data are always allowed for Unicode, but for EBCDIC and ASCII, the ...

  7. NYOJ题目34韩信点兵

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAskAAAHiCAIAAACV1MbSAAAgAElEQVR4nO3dPXLjONeG4W8TyrUQx1 ...

  8. mysql的事务处理

    事务用于保证数据的一致性,它由一组相关的DML语句组成,该组的DML语句要么全部成功,要么全部失败. 示例: 银行账单 $mysqli=new mysqli("localhost" ...

  9. 《C#本质论》读书笔记(14)支持标准查询操作符的集合接口

      14.2.集合初始化器 使用集合初始化器,程序员可以采用和数组相似的方式,在集合的实例化期间用一套初始的成员来构造这个集合. 如果没有集合初始化器,就只有在集合实例化后才能显示添加到集合中--例如 ...

  10. 在ubuntu上搭建开发环境9---Ubuntu删除ibus出现的问题及解决

    删除 ibus输入法: sudo apt-get install ibus 我们会遇到下面的问题 Ubuntu 14.04 系统设置很多选项消失. 其实遇到这个问题的一个最主要的原因是之前执行过卸载i ...