state&actions&reducer&subscriptions
state holds your js apps state.
1
2
3
4
5
6
7
8
9
10{
todos: [{
text: 'sleeping',
completed: true
}, {
text: 'reading',
completed: false
}],
visibilityFilter: 'SHOW_COMPLETED'
}actions are called by your app.
1
2
3
4{
type: 'ADD_TODO',
text: 'take some rest'
}reducers handle the transformations between actions & store.
1
2
3
4
5
6
7
8
9
10
11
12
13function todos(state = {}, action) {
switch(action.type) {
case 'ADD_TODO':
return state.concat({
text: action.text,
completed: false
})
case 'TOGGLE_TODO':
return state.map((todo, index) => action.index === index ? {...todo, completed: !todo.completed} : todo)
default:
return state
}
}subscriptions listen for changes to the store.
三原则
- the single immutable state tree.
- describing state changes with actions.
state 只读,需要通过dispatch actions 来改变state。 - a pure function reducer describe state mutations.
接受prevState 和 action,返回nextState。
pure and impure functions
纯函数 输入决定输出,不会改变输入的内容1
2
3function sliceArr(x) {
return x.slice(1,2);
}
非纯函数1
2
3function spliceArr(x) {
return x.splice(1, 1)
}
Store
- holds the current application state object.
getState() - allows you to dispatch actions.
dispatch() - when you create it, you need to specify the reducer that tells how state is updated with actions.
subscribe()createStore
接受一个参数reducer
getState 返回当前的state。
subscribe 接受一个参数listener,返回一个unsubscribe方法。
dispatch 接受一个action为参数,调用reducer方法,生成新的state。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24const createStore = reducer => {
let state;
let listeners = [];
const getState = () => state
const dispatch = (action) => {
state = reducer(state, action);
listeners.forEach(listener => listener())
}
const subsrcibe = (listener) => {
listeners.push(listener)
// 返回一个方法unsubscribe
return () => {
listeners = listeners.filter(l => l !== listener)
}
}
// initial state
dispatch({})
return { getState, dispatch, subscribe}
}
combineReducers
reducer composition calls existing reducers to manage their parts of the state, then combine the parts into a single state object.
接受reducers作为参数,返回一个reducer function。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26// reducer composition
const todoApp = (state={}, action) => {
// todos/visibilityFilter reducer
return {
todos: todos(state.todos, action),
visibilityFilter: visibilityFilter(state.visibilityFilter, action)
}
}
/*
*combineReducers
*接受一个参数 reducers (object)
*返回一个reducer
*/
const combineReducers = reducers => {
// reducer 接受两个参数state,action,返回一个新的state
return (state = {}, action) => {
// reduce 累加器
return Object.keys(reducers).reduce((nextState, key) => {
nextState[key] = reducers[key](state[key], action)
return nextState
}, {})
}
}
const todoApp = combineReducers({ todos, visibilityFilter })
bindActionCreators
将action包装成直接可被调用的函数。1
2
3
4
5const bindActionCreators = (actionCreators, dispatch) => {
return Object.keys(actionCreators).reduce((total, key) => {
total[key] = (...args) => dispatch(actionCreators[key](...args))
}, {})
}
todo list app
1 | <!--redux store--> |
1 | <!--react jsx--> |