redux-tutorial
//01
var actionCreator = function() {
return {
type: 'AN_ACTION'
}
}
console.log(actionCreator()) // 输出: { type: 'AN_ACTION' }
//02
import { createStore } from 'redux'
var store = createStore(() => {})
//03
import { createStore } from 'redux'
var store_0 = createStore(() => {})
var reducer = function (...args) {
console.log('Reducer was called with args', args)
}
var store_1 = createStore(reducer)
//Reducer was called with args [ undefined, { type: '@@redux/INIT' } ]
//04
import { createStore } from 'redux'
var reducer_0 = function (state, action) {
console.log('reducer_0 was called with state', state, 'and action', action)
}
var store_0 = createStore(reducer_0)
// reducer_0 was called with state undefined and action { type: '@@redux/INIT' }
console.log('store_0 state after initialization:', store_0.getState())
// store_0 state after initialization: undefined
var reducer_1 = function (state, action) {
console.log('reducer_1 was called with state', state, 'and action', action)
if (typeof state === 'undefined') {
return {}
}
return state;
}
var store_1 = createStore(reducer_1)
// reducer_1 was called with state undefined and action { type: '@@redux/INIT' }
console.log('store_1 state after initialization:', store_1.getState())
// store_1 state after initialization: {}
//ES6 写法
var reducer_2 = function (state = {}, action) {
console.log('reducer_2 was called with state', state, 'and action', action)
return state;
}
var store_2 = createStore(reducer_2)
// reducer_2 was called with state {} and action { type: '@@redux/INIT' }
console.log('store_2 state after initialization:', store_2.getState())
// store_2 state after initialization: {}
var reducer_3 = function (state = {}, action) {
console.log('reducer_3 was called with state', state, 'and action', action)
switch (action.type) {
case 'SAY_SOMETHING':
return {
...state,
message: action.value
}
default:
return state;
}
}
var store_3 = createStore(reducer_3)
// reducer_3 was called with state {} and action { type: '@@redux/INIT' }
console.log('store_3 state after initialization:', store_3.getState())
// store_3 state after initialization: {}
//05
var reducer_0 = function (state = {}, action) {
console.log('reducer_0 was called with state', state, 'and action', action)
switch (action.type) {
case 'SAY_SOMETHING':
return {
...state,
message: action.value
}
default:
return state;
}
}
var reducer_1 = function (state = {}, action) {
console.log('reducer_1 was called with state', state, 'and action', action)
switch (action.type) {
case 'SAY_SOMETHING':
return {
...state,
message: action.value
}
case 'DO_SOMETHING':
// ...
case 'LEARN_SOMETHING':
// ...
case 'HEAR_SOMETHING':
// ...
case 'GO_SOMEWHERE':
// ...
// etc.
default:
return state;
}
}
//多个 reducer 打包
var userReducer = function (state = {}, action) {
console.log('userReducer was called with state', state, 'and action', action)
switch (action.type) {
// etc.
default:
return state;
}
}
var itemsReducer = function (state = [], action) {
console.log('itemsReducer was called with state', state, 'and action', action)
switch (action.type) {
// etc.
default:
return state;
}
}
import { createStore, combineReducers } from 'redux'
var reducer = combineReducers({
user: userReducer,
items: itemsReducer
})
// userReducer was called with state {} and action { type: '@@redux/INIT' }
// userReducer was called with state {} and action { type: '@@redux/PROBE_UNKNOWN_ACTION_9.r.k.r.i.c.n.m.i' }
// itemsReducer was called with state [] and action { type: '@@redux/INIT' }
// itemsReducer was called with state [] and action { type: '@@redux/PROBE_UNKNOWN_ACTION_4.f.i.z.l.3.7.s.y.v.i' }
var store_0 = createStore(reducer)
// userReducer was called with state {} and action { type: '@@redux/INIT' }
// itemsReducer was called with state [] and action { type: '@@redux/INIT' }
console.log('store_0 state after initialization:', store_0.getState())
// store_0 state after initialization: { user: {}, items: [] }
var userReducer = function (state = {}, action) {
console.log('userReducer was called with state', state, 'and action', action)
switch (action.type) {
case 'SET_NAME':
return {
...state,
name: action.name
}
default:
return state;
}
}
var itemsReducer = function (state = [], action) {
console.log('itemsReducer was called with state', state, 'and action', action)
switch (action.type) {
case 'ADD_ITEM':
return [
...state,
action.item
]
default:
return state;
}
}
import { createStore, combineReducers } from 'redux'
var reducer = combineReducers({
user: userReducer,
items: itemsReducer
})
var store_0 = createStore(reducer)
console.log('store_0 state after initialization:', store_0.getState())
// store_0 state after initialization: { user: {}, items: [] }
store_0.dispatch({
type: 'AN_ACTION'
})
// userReducer was called with state {} and action { type: 'AN_ACTION' }
// itemsReducer was called with state [] and action { type: 'AN_ACTION' }
console.log('store_0 state after action AN_ACTION:', store_0.getState())
// store_0 state after action AN_ACTION: { user: {}, items: [] }
var setNameActionCreator = function (name) {
return {
type: 'SET_NAME',
name: name
}
}
store_0.dispatch(setNameActionCreator('bob'))
// userReducer was called with state {} and action { type: 'SET_NAME', name: 'bob' }
// itemsReducer was called with state [] and action { type: 'SET_NAME', name: 'bob' }
console.log('store_0 state after action SET_NAME:', store_0.getState())
// store_0 state after action SET_NAME: { user: { name: 'bob' }, items: [] }
//非异步
import { createStore, combineReducers } from 'redux'
var reducer = combineReducers({
speaker: function (state = {}, action) {
console.log('speaker was called with state', state, 'and action', action)
switch (action.type) {
case 'SAY':
return {
...state,
message: action.message
}
default:
return state;
}
}
})
var store_0 = createStore(reducer)
var sayActionCreator = function (message) {
return {
type: 'SAY',
message
}
}
console.log(new Date());
store_0.dispatch(sayActionCreator('Hi'))
// Sun Aug 02 2015 01:03:05 GMT+0200 (CEST)
// speaker was called with state {} and action { type: 'SAY', message: 'Hi' }
console.log(new Date());
console.log('store_0 state after action SAY:', store_0.getState())
// Sun Aug 02 2015 01:03:05 GMT+0200 (CEST)
// store_0 state after action SAY: { speaker: { message: 'Hi' } }
//错误的异步方式,会提示使用中间件
var asyncSayActionCreator_1 = function (message) {
return function (dispatch) {
setTimeout(function () {
dispatch({
type: 'SAY',
message
})
}, 2000)
}
}
var anyMiddleware = function ({ dispatch, getState }) {
return function(next) {
return function (action) {
// 你的中间件业务相关代码
}
}
}
// 如上所述,中间件由三个嵌套的函数构成(会依次调用):
// 1) 第一层向其余两层提供分发函数和 getState 函数(因为你的中间件或 action creator 可能需要从 state 中读取数据)
// 2) 第二层提供 next 函数,它允许你显式的将处理过的输入传递给下一个中间件或 Redux(这样 Redux 才能调用所有 reducer)。
// 3) 第三层提供从上一个中间件或从 dispatch 传递来的 action,这个 action 可以调用下一个中间件(让 action 继续流动) 或者 以想要的方式处理 action。
// 柯里化可以简化上述函数, "curry" may come any functional programming library (lodash, ramda, etc.)
var thunkMiddleware = curry(
({dispatch, getState}, next, action) => (
// 你的中间件业务相关代码
)
);
//https://github.com/gaearon/redux-thunk
var thunkMiddleware = function ({ dispatch, getState }) {
// console.log('Enter thunkMiddleware');
return function(next) {
// console.log('Function "next" provided:', next);
return function (action) {
// console.log('Handling action:', action);
return typeof action === 'function' ?
action(dispatch, getState) :
next(action)
}
}
}
// applyMiddleware https://github.com/rackt/redux/blob/v1.0.0-rc/src/utils/applyMiddleware.js
import { createStore, combineReducers, applyMiddleware } from 'redux'
// 针对多个中间件, 使用:applyMiddleware(middleware1, middleware2, ...)(createStore)
const finalCreateStore = applyMiddleware(thunkMiddleware)(createStore)
var reducer = combineReducers({
speaker: function (state = {}, action) {
console.log('speaker was called with state', state, 'and action', action)
switch (action.type) {
case 'SAY':
return {
...state,
message: action.message
}
default:
return state
}
}
})
const store_0 = finalCreateStore(reducer)
// speaker was called with state {} and action { type: '@@redux/INIT' }
// speaker was called with state {} and action { type: '@@redux/PROBE_UNKNOWN_ACTION_s.b.4.z.a.x.a.j.o.r' }
// speaker was called with state {} and action { type: '@@redux/INIT' }
var asyncSayActionCreator_1 = function (message) {
return function (dispatch) {
setTimeout(function () {
console.log(new Date(), 'Dispatch action now:')
dispatch({
type: 'SAY',
message
})
}, 2000)
}
}
console.log("\n", new Date(), 'Running our async action creator:', "\n")
// Mon Aug 03 2015 00:01:20 GMT+0200 (CEST) Running our async action creator:
store_0.dispatch(asyncSayActionCreator_1('Hi'))
// Mon Aug 03 2015 00:01:22 GMT+0200 (CEST) 'Dispatch action now:'
// speaker was called with state {} and action { type: 'SAY', message: 'Hi' }
function logMiddleware ({ dispatch, getState }) {
return function(next) {
return function (action) {
console.log('logMiddleware action received:', action)
return next(action)
}
}
}
function discardMiddleware ({ dispatch, getState }) {
return function(next) {
return function (action) {
console.log('discardMiddleware action received:', action)
}
}
}
store.subscribe(function() {
// retrieve latest store state here
// Ex:
console.log(store.getState());
})
import { createStore, combineReducers } from 'redux'
var itemsReducer = function (state = [], action) {
console.log('itemsReducer was called with state', state, 'and action', action)
switch (action.type) {
case 'ADD_ITEM':
return [
...state,
action.item
]
default:
return state;
}
}
var reducer = combineReducers({ items: itemsReducer })
var store_0 = createStore(reducer)
store_0.subscribe(function() {
console.log('store_0 has been updated. Latest store state:', store_0.getState());
// 在这里更新你的视图
})
var addItemActionCreator = function (item) {
return {
type: 'ADD_ITEM',
item: item
}
}
store_0.dispatch(addItemActionCreator({ id: 1234, description: 'anything' }))
// store_0 has been updated. Latest store state: { items: [ { id: 1234, description: 'anything' } ] }