背景
最近需要使用react技术栈,需要掌握react,redux和redux-saga,然而我只是简单的写过react。刷了几遍文档还是一头雾水,决定写过小demo练手加深下印象。
就不详细介绍上面的技术了,简单来说redux就是管理状态的,但是对于异步的处理不是很完善,这里就需要用到redux-saga了。redux-saga的异步处理用到了生成器和迭代器的相关知识,不熟悉的同学可以了解下我之前的文章
这次的demo打算写一个输入框,输入拼音会返回对应的城市列表。并尽可能多的使用redux-saga的特性
起步
首先是使用create-react-app创建新的项目,并npm install react-redux redux redux-saga --save
上网随便搜索了一段城市信息的json,保存为city.js
|
|
接着是构思state,state有两个值,一个是value代表输入的值,另一个是数组list,代表筛选的结果
reducers.js
设置两个action,一个是设置value,一个是设置list
|
|
APP.js
App为纯函数组件,react-redux的connect方法中传入两个参数,mapStateToProps将state传入App的props,mapActionToProps讲handleChange传入App,当调用handleChange时,会调用INPUT这个action
|
|
接着是我们的主角saga.js
takeEvery可以监听对应的action,如果为*号则监听所有的action,如果action.type匹配,调用对应的回调函数。put可以主动去触发action,在这里触发了获取的城市结果
|
|
input函数也可以使用take来替代takeEvery
|
|
接下来是最复杂的index.js部分
|
|
到这里,城市拼音输入框就初步完成了
进阶
取消
先加入如果输入数字的话,立刻停止查询并console报错的功能
修改saga.js
首先,导入fork和cancel两个函数,redux-saga的cancel只能取消fork的任务
import {takeEvery, put, take, cancel, fork} from 'redux-saga/effects'
新加一个check函数,跟之前的input有点类型,如果监测到有数字,会调用CANCEL
|
|
加入函数main, 首先添加使用fork操作,将input任务保存为i,在碰到cancel的时候,取消该任务,并重新开始新的任务
|
|
最后导出main
export default main
channel
令函数是依次查询,只有之前的查询完成后,才继续查询后面的
引用actionChannel 的effect,修改函数input
|
|