摘要:背景項目用的是全家桶,之前有同事用改進了一波,一直都沒去研究。這次的打算寫一個輸入框,輸入拼音會返回對應的城市列表。
背景
項目用的是react全家桶, 之前有同事用redux-saga 改進了一波, 一直都沒去研究。 前幾天趁有空,也去學習了下, 寫了個簡單的demo練練手, 在這里簡單分享一下。
這次的demo打算寫一個輸入框,輸入拼音會返回對應的城市列表。并盡可能多的使用redux-saga的特性
起步首先是使用 create-react-app 創建新的項目,并npm install react-redux redux redux-saga --save
上網隨便搜索了一段城市信息的json,保存為city.js
const cities = [{label:"北京Beijing010",name:"北京",pinyin:"Beijing",zip:"010"}, {label:"重慶Chongqing023",name:"重慶",pinyin:"Chongqing",zip:"023"}, {label:"上海Shanghai021",name:"上海",pinyin:"Shanghai",zip:"021"},...] export default cites;
接著是構思state,state有兩個值,一個是value代表輸入的值,另一個是數組list,代表篩選的結果
reducers.js // 設置兩個action,一個是設置value,一個是設置list const reducer = (state, action) => { switch (action.type) { case "INPUT": return {...state, value: action.payload} case "SET_LIST": return {...state, list: action.payload} } return {...state} } export default reducer
APP.js
App為純函數組件,react-redux的connect方法中傳入兩個參數,mapStateToProps將state傳入App的props,mapActionToProps講handleChange傳入App,當調用handleChange時,會調用INPUT這個action
import React, { Component } from "react"; import "./App.css"; import { connect } from "react-redux" const App = props => () const mapStateToProps = state => ({ value: state.value, list: state.list }) const mapActionToProps = dispatch => ({ handleChange: v => dispatch({ type: "INPUT", payload: v.target.value }) }) // export default App export default connect(mapStateToProps, mapActionToProps)(App);{props.list.map(i =>
- {i.name}
)}
接著是我們的主角saga.js
takeEvery可以監聽對應的action,如果為*號則監聽所有的action,如果action.type匹配,調用對應的回調函數。
put可以主動去觸發action,在這里觸發了獲取的城市結果
import {takeEvery, put, take} from "redux-saga/effects" import cities from "./city" function* input() { yield takeEvery("INPUT", function* (v) { let filterCities = yield getData(v.payload) yield put({type: "SET_LIST", payload: filterCities.slice(0, 10)}) }); } function getData (v) { return new Promise(function (res, rej) { setTimeout(() => res(cities.filter(i => i.pinyin.toUpperCase().includes(v.toUpperCase()))), 1000) }) } export default input input函數也可以使用take來替代takeEvery function* input() { while (true) { let v = yield take("INPUT") let filterCities = yield getData(v) yield put({type: "SET_LIST", payload: filterCities.slice(0, 10)}) } }
接下來是最復雜的index.js部分
import React from "react"; import { render } from "react-dom"; import "./index.css"; import App from "./App"; import registerServiceWorker from "./registerServiceWorker"; import { Provider } from "react-redux" import createSagaMiddleware from "redux-saga" import { createStore, applyMiddleware } from "redux" import reducers from "./reducers" import saga from "./sagas" const sagaMiddleware = createSagaMiddleware() const store = createStore(reducers, {value: "", list: []}, applyMiddleware(sagaMiddleware)) sagaMiddleware.run(saga) render(, document.getElementById("root")); registerServiceWorker();
到這里,城市拼音輸入框就初步完成了
進階取消
先加入如果輸入數字的話,立刻停止查詢并console報錯的功能
修改saga.js
首先,導入fork和cancel兩個函數,redux-saga的cancel只能取消fork的任務
import {takeEvery, put, take, cancel, fork} from "redux-saga/effects" // 新加一個check函數,跟之前的input有點類型,如果監測到有數字,會調用CANCEL function* check () { yield takeEvery("INPUT", function* (v) { if (/d+/.test(v.payload)) { console.log("x ") yield put({type: "CANCEL"}) } }) }
加入函數main, 首先添加使用fork操作,將input任務保存為i,在碰到cancel的時候,取消該任務,并重新開始新的任務
function* main () { yield fork(check) let i = yield fork(input) while (true) { yield take("CANCEL") console.log("cancel") yield cancel(i) i = yield fork(input) } }
最后導出main
export default main
channel
令函數是依次查詢,只有之前的查詢完成后,才繼續查詢后面的
引用actionChannel 的effect,修改函數input:
function* input () { const inputChan = yield actionChannel("INPUT") while (true) { const v = yield take(inputChan) const filterCities = yield call(getData, v) console.log("done") yield put({type: "SET_LIST", payload: filterCities.slice(0, 10)}) } }
END
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/95896.html
摘要:通過創建將所有的異步操作邏輯收集在一個地方集中處理,可以用來代替中間件。 redux-saga框架使用詳解及Demo教程 前面我們講解過redux框架和dva框架的基本使用,因為dva框架中effects模塊設計到了redux-saga中的知識點,可能有的同學們會用dva框架,但是對redux-saga又不是很熟悉,今天我們就來簡單的講解下saga框架的主要API和如何配合redux框...
摘要:下面會從淺到深,淡淡在閱讀源碼過程中自己的理解。分拆子頁面后,每一個子頁面對應一個文件。總結上面就是最早版本的源碼,很簡潔的使用了等其目的也很簡單簡化相關生態的繁瑣邏輯參考源碼地址 ??dva的思想還是很不錯的,大大提升了開發效率,dva集成了Redux以及Redux的中間件Redux-saga,以及React-router等等。得益于Redux的狀態管理,以及Redux-saga中...
摘要:下面會從淺到深,淡淡在閱讀源碼過程中自己的理解。分拆子頁面后,每一個子頁面對應一個文件。總結上面就是最早版本的源碼,很簡潔的使用了等其目的也很簡單簡化相關生態的繁瑣邏輯參考源碼地址 ??dva的思想還是很不錯的,大大提升了開發效率,dva集成了Redux以及Redux的中間件Redux-saga,以及React-router等等。得益于Redux的狀態管理,以及Redux-saga中...
摘要:下面會從淺到深,淡淡在閱讀源碼過程中自己的理解。分拆子頁面后,每一個子頁面對應一個文件。總結上面就是最早版本的源碼,很簡潔的使用了等其目的也很簡單簡化相關生態的繁瑣邏輯參考源碼地址 ??dva的思想還是很不錯的,大大提升了開發效率,dva集成了Redux以及Redux的中間件Redux-saga,以及React-router等等。得益于Redux的狀態管理,以及Redux-saga中...
閱讀 2314·2021-11-08 13:13
閱讀 1245·2021-10-09 09:41
閱讀 1683·2021-09-02 15:40
閱讀 3186·2021-08-17 10:13
閱讀 2546·2019-08-29 16:33
閱讀 3122·2019-08-29 13:17
閱讀 3131·2019-08-29 11:00
閱讀 3295·2019-08-26 13:40