React Middleware



Middleware


  • dispatch()メソッドはstoreの動作コード
  • をブロックする.
  • 非同期動作可能
  • 非同期関数1つの内で複数のスケジューリングを実行できます

    Redux-thunk

  • リード非同期タスクを処理する際に最もよく使用されるミドルウェア
  • 動作オブジェクト
  • ではなくdispatch関数
  • thunkは動作生成関数を作成する=dispatch関数の場合、この関数からdispatchgetStateをパラメータとして取得する必要があり、thunkはこの関数
  • を作成する.
  • thunkを用いる、動作生成器は、必要な値をパラメータとして関数
  • を返すことができる.
  • アクション作成関数は、タイプとペイロードを含むオブジェクトを作成し、これらのオブジェクトを返す役割を果たし、thunkミドルウェアはAPIリクエストまたは非同期処理も担当するため、本来の役割がぼやけてしまいます.
  • $ npm i redux-thunk
    function createThunkMiddleware(extraArgument){
      return ({dispatch,getState})=> (next) => (action) => {
      	if(typeof action === 'function'){
        	return action(dispatch, getState, extraArgument)
        }
        
        return next(action);
      }
    }
    
    const thunk = createThunkMiddleware()
    thunk.withExtraArgument = createThunkMiddleware;
    
    export default thunk;

    Redux-saga

  • に対して動作するリスナー
  • thunkは関数またはオブジェクトを返し、sagaはオブジェクト
  • のみを返す.
  • ES 6のgenerator構文
  • を使用
  • thunkよりも多くの機能を提供する
  • 使用方法

    $ npm i redux-saga
    const sagaMiddleware = createSagaMiddleware();
    ...
    composeWithDevTools(applyMiddleware(sagaMiddleware))
    ...
    sagaMiddleware.run(rootSaga)

    sagaモジュール化

    // sagas/index.js -- rootsaga
    import {all, fork} from 'redux-saga/effects'
    import postSaga from './post'
    import userSaga from './user'
    
    export default function * rootSaga(){
        yield all([
            fork(userSaga),
            fork(postSaga)
        ])
    }
    // sagas/user.js
    import {all,fork} from 'redux-saga'
    
    function* logIn(){
        try{
            //const result = yield call(loginAPI)        
            yield put({
                type:'LOG_IN_SUCCSS',
                data:result.data
            })
        }catch(err){
            yield put({
                type:'LOG_IN_FAILURE',
                data:err.response.data
            });
        }    
    }
    function loginAPI(){
        return axios.post('/api/login')
    }
    
    function* logOut(){
        try {
            const result = yield call(login)
            
        } catch (error) {
            
        }
    }
    
    
    function* watchLogin(){
        yield take('LOG_IN_REQUEST',logIn);
    }
    function* watchLogout(){
        yield take('LOG_OUT_REQUEST');
    }
    
    export default function* userSaga(){
        yield all([
            fork(watchLogIn),
            fork(watchLogOut)        
        ])
    }

    saga-effect

    import {all, call, fork, put, take} from 'redux-saga/effects'
    
    function loginAPI(){
        return axios.post('/api/login')
    }
    
    function* logIn(){
        try{
            const result = yield call(loginAPI)
            yield put({
                type:'LOG_IN_SUCCSS',
                data:result.data
            })
        }catch(err){
            yield put({
                type:'LOG_IN_FAILURE',
                data:err.response.data
            });
        }
        
    }
    
    function* watchLogin(){
        yield take('LOG_IN',logIn);
    }
    
    function* watchLogout(){
        yield take('LOG_OUT');
    }
    
    function* watchAddPost(){
        yield take('ADD_POST')
    }
    
    export default function * rootSaga(){
        yield all([
            call(watchLogin), //fork
            call(watchLogout),
            call(watchAddPost),
        ])
    }

    put

  • アクションを呼び出すdispatch()ロール
  • call

  • Function.prototype.例えばcall()
  • 呼び出し
  • 同期関数
  • によってapiが呼び出されると、応答
  • が待機する.

    fork


    呼び出し
  • 非同期関数
  • が応答する前に、次のステップ
  • が実行する.

    take

  • 動作
  • は1回のみ実行する.

    takeEvery


    動作毎に
  • ,
  • を実行する.
  • takeは1回しか動作しないので、
  • の代わりにwhileドアで包みます.

    takeLatest

  • 動作が呼び出されたときに同じ動作が実行されている場合、その動作は破棄され、最後の呼び出しのみが実行されます.
  • 要求の応答をキャンセルする
  • POST、PUT、DELETEなどのリソース変更方法は
  • を使用する.

    delay

  • settimeoutと同じキャラクター
  • throttle

  • は、最後の関数が呼び出し後しばらくの間、
  • に呼び出されないことを保証する.

    debouncing

  • を連続的に呼び出す関数のうち、最後の(または最初の)関数のみを呼び出す関数は
  • である.
    📑 reference
  • https://react.vlpt.us/redux-middleware/04-redux-thunk.html
  • https://medium.com/humanscape-tech/redux%EC%99%80-%EB%AF%B8%EB%93%A4%EC%9B%A8%EC%96%B4-thunk-saga-43bb012503e4
  • https://github.com/reduxjs/redux-thunk