Redux-saga初探侦
5014 ワード
背景
プロジェクトはreact家族の桶を使っています.以前は同僚がredux-sagaで改善しました.ずっと研究に行きませんでした.先日暇があったら、勉強に行きました.簡単なデモトレーナーを書いて、ここで簡単にシェアしてみました.
今回のデモは入力枠を書くつもりです.ピンインを入力すれば対応する都市リストに戻ります.そしてできるだけ多くのredux-sagaを使う特性
スタートをきる
まず、
インターネットを利用して気軽に都市情報のjsonを検索して、city.jsとして保存します.
Appは純関数コンポーネントであり、react-reduxのconnect方法では二つのパラメータが導入されています.mapStation ToPropsはstateをAppのpropsに導入し、MapAct ToPropsはhandleChangeをアプリに導入し、handle Changeを呼び出したときにINPUTというactionを呼び出します.
takeeveryは対応するactionを傍受できます.*番なら全てのactionを傍受します.もしaction.typeが合ったら、対応するコールバック関数を呼び出します.
putは自発的にactionを触発することができて、ここで獲得する都市の結果を触発しました.
階段を進める
まず数字を入力すると、すぐに検索を停止して、soneエラーを知らせる機能を追加します.
saga.jsを修正します
まず、forkとcancelの2つの関数を導入して、redux-sagaのcancelはforkの任務を取り消すことしかできません.
actionChanelのeffectを引用して、関数inputを修正します.
プロジェクトはreact家族の桶を使っています.以前は同僚がredux-sagaで改善しました.ずっと研究に行きませんでした.先日暇があったら、勉強に行きました.簡単なデモトレーナーを書いて、ここで簡単にシェアしてみました.
今回のデモは入力枠を書くつもりです.ピンインを入力すれば対応する都市リストに戻ります.そしてできるだけ多くの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は入力の値を表します.もう一つは配列リストです.フィルタの結果を表します.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
P.jsAppは純関数コンポーネントであり、react-reduxのconnect方法では二つのパラメータが導入されています.mapStation ToPropsはstateをAppのpropsに導入し、MapAct ToPropsはhandleChangeをアプリに導入し、handle Changeを呼び出したときにINPUTというactionを呼び出します.
import React, { Component } from 'react';
import './App.css';
import { connect } from 'react-redux'
const App = props =>
(
{props.list.map(i =>
- {i.name}
)}
)
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);
次は私たちの主役の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();
ここで、都市ピンイン入力ボックスは一応完成しました.階段を進める
まず数字を入力すると、すぐに検索を停止して、soneエラーを知らせる機能を追加します.
saga.jsを修正します
まず、forkとcancelの2つの関数を導入して、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)
}
}
最後にメールをエクスポートしますexport default main
chanel命令関数は順を追って調べますが、前のクエリが完了してから、後の確認を続けます.actionChanelの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