1. 程式人生 > 其它 >react系列學習(二)——react-saga使用方法

react系列學習(二)——react-saga使用方法

技術標籤:react

1,上一篇記錄了redux,redux是同步的,既發出action指令後,reducer立即計算store,並返回。那麼非同步問題該如何解決?從後臺請求獲取的資料如何儲存到store?這就是中介軟體的作用,也就是redux-saga的用處。

2,index檔案同樣是合併多個saga,便於管理程式碼,和reducer的合併一樣

import {all} from 'redux-saga/effects';
import helloSaga from './helloSage';
import watchIncrementAsync from './incrementAsyncSaga'


export default function* rootSaga() {
  yield all([
    helloSaga(),
    watchIncrementAsync()
  ]);
}

3,下面以incrementAsyncSaga.js為例(功能為從後臺請求使用者名稱,顯示在頁面上。)

saga可以視為是一個reducer,能夠處理非同步的reducer。所以saga同樣是接收action指令,執行相應操作,只不過saga不進行計算,而是傳送新的指令到reducer,讓reducer來計算新的store。

import { put, takeEvery, all, call } from 'redux-saga/effects';
import { delay } from 'redux-saga';
import { addTodo, showData } from '../creatAction';
import * as ct from '../creatAction/action';

function getData() {
  return fetch("/api/test/profile",{
    method:"GET",
    credentials: 'include'
  }).then((response)=>{
      console.log(response);
      return response.json()
  }).then((response)=>{
      console.log(response)
      return response;
  }).catch((error)=>{
      console.log(error)
  })

}

// Our worker Saga: 將執行非同步的 increment 任務
function* incrementAsync() {
  const resData = yield call(getData);
  console.log(resData.user)
  yield put(showData(resData.user));
  // yield put(addTodo(1))
}

// Our watcher Saga: 在每個 INCREMENT_ASYNC action spawn 一個新的 incrementAsync 任務
export default function* watchIncrementAsync() {
  yield takeEvery(ct.ASYNC_TODO, incrementAsync)
}

tackEvery,第一個引數為action,第二個引數為要執行的方法。當action匹配時,便執行incrementAsync;

incrementAsync方法中,首先通過fetch向後臺請求資料,請求結束後,返回請求結果,第二步,yield put(showData(resData.user));傳送action,改變store。put相當於store.dispatch。

4,使用方法

<h1>{store.getState().showUser}</h1> 
<button onClick={() => store.dispatch(asyncTodo())}>非同步</button>

creatAction

import * as ct from './action';

//非同步
export function asyncTodo(text) {
  return {
    type: ct.ASYNC_TODO,
    text
  }
}

//顯示使用者名稱
export function showData(text) {
  return {
    type: ct.ASYNC_USER,
    text
  }
}

reducer

import * as ct from '../creatAction/action';
const showUserRducer = (state='haha', action) => {
  switch (action.type) {
    case ct.ASYNC_USER: return action.text;
    default: return state;
  }
};

export default showUserRducer;

5,總結

redux-saga做的事情是,首先發送請求,請求成功後,在向reducer傳送指令,重新計算store。

主要應用es6的Generator函式

function*incrementAsync(){

constresData=yieldcall(getData);

yieldput(showData(resData.user));

}