经过上一章的环境搭建,接下里在本篇文章中去学习官网的一个例子。
TodoList ;代办项的demo
效果如图
因为redux的state的是可以预测的。
思路如下:
1.demo中所涉及的数据(state)的管理 就是 Todolist 和 visibilityFilter
2.理解下redux的三大要素:
Action :是把数据从应用(译者注:这里之所以不叫 view 是因为这些数据有可能是服务器响应,用户输入或其它非 view 的数据 )传到 store 的有效载荷。它是 store 数据的唯一来源。一般来说你会通过 store.dispatch()
将 action 传到 store。
Reducers 指定了应用状态的变化如何响应 actions 并发送到 store 的,记住 actions 只是描述了有事情发生了这一事实,并没有描述应用如何更新 state。
reducer是纯函数 ,下面是纯函数的要求
- 修改传入参数;
- 执行有副作用的操作,如 API 请求和路由跳转;
- 调用非纯函数,如
Date.now()
或Math.random()
redux提供将多个reducer组合到一起 combineReducer({a,b,c})
Store 就是把Reducers 和Action联系到一起的对象
Store 有以下职责:
- 维持应用的 state;
- 提供
getState()
方法获取 state; - 提供
dispatch(action)
方法更新 state; - 通过
subscribe(listener)
注册监听器; - 通过
subscribe(listener)
返回的函数注销监听器。
3.根据UI来看 ,分成三个组件 AddTodo,VisibleTodolist,Footer 放在components路径下。与container不同的是 component下面的组件不需要跟dispatch打交道
而是直接显示。
4.开始写action
let nextTodoId = 0 export const addTodo = function(text){ return { type:"ADD_TODO", id:nextTodoId++, text } } export const toggleTodo = function(id){ return { type:"TOGGLE_TODO", id } } export const setVisibility = function(filter){ return { type:"SET_VISIBILITY_FILTER", filter } }
5.开始写reducer
分为todo.js 和 visibilityFilter.js 这里用到了一些es6d的语法 map assign 等 reducer是为了返回新的state ,很像vuex里面的mutation
const todo = function (state = [], action) { switch (action.type) { case 'ADD_TODO': return [ ...state, { text: action.text, id: action.id, completed: false } ] case 'TOGGLE_TODO': return state.map(todo => { return todo.id === action.id ? (Object.assign({}, todo, { completed: !todo.completed })) : todo }) default: return state } } export default todo
const visibilityFilter=function(state='SHOW_ALL',action){ switch (action.type) { case 'SET_VISIBILITY_FILTER': return action.filter default: return state } } export default visibilityFilter
6.开始写 components 和 containers 里组件
VisibleTodoList =>TodoList=>Todo
Footer => FooterLink =>Link
AddTodo