redux-saga如何使用?

redux-saga

redux中文版文档
redux-saga中文文档
在线请求api
redux-devtools-extension 调试工具 – 使用 redux-devtools-extension 查看 Redux 中状态变化
本文的案例是用的redux和redux-saga,这里的案例是用的redux、redux-saga

概述

redux-saga 是 redux 一个中间件,用于解决异步问题。

es6 Generator

解决地狱回调问题,通过 yield 关键字,可以让函数的执行流挂起。
使用在线工具验证:https://jsbin.com/musedihito/edit?js,console
参考:
https://blog.csdn.net/tcy83/article/details/80427195

Redux -saga 案例流程

main.js

首先在main.js里引入createStore 和 createSagaMiddleware, 并创建saga中间件和store

import * as React from 'react'
import ReactDOM from 'react-dom'
import { createStore, applyMiddleware } from 'redux'; // store、中间件
import createSagaMiddleware from 'redux-saga'; // ***1.saga引入createSagaMiddleware***

import Counter from './components/Counter'
import reducer from './reducers'
import rootSaga from './sagas'
// ***2.创建saga中间***件
const sagaMiddleware = createSagaMiddleware()
const store = createStore(reducer, applyMiddleware(sagaMiddleware))
sagaMiddleware.run(rootSaga)

const action = type => store.dispatch({ type })

function render() {
  ReactDOM.render(
    <Counter
      value={store.getState()}
      onIncrement={() => action('INCREMENT')}
      onDecrement={() => action('DECREMENT')}
      onIncrementIfOdd={() => action('INCREMENT_IF_ODD')}
      onIncrementAsync={() => action('INCREMENT_ASYNC')}
    />,
    document.getElementById('root'),
  )
}
render()
store.subscribe(render)

components/Counter.js

import * as React from 'react'
import PropTypes from 'prop-types'

const Counter = ({ value, onIncrement, onIncrementAsync, onDecrement, onIncrementIfOdd }) => (
  <p>
    Clicked: {value} times <button onClick={onIncrement}>+</button> <button onClick={onDecrement}>-</button>{' '}
    <button onClick={onIncrementIfOdd}>Increment if odd</button>{' '}
    <button onClick={onIncrementAsync}>Increment async</button>
  </p>
)

Counter.propTypes = {
  value: PropTypes.number.isRequired,
  onIncrement: PropTypes.func.isRequired,
  onDecrement: PropTypes.func.isRequired,
  onIncrementAsync: PropTypes.func.isRequired,
  onIncrementIfOdd: PropTypes.func.isRequired,
}

export default Counter

什么是prop-types?
什么是prop-types

reducers/index.js
export default function counter(state = 0, action) {
  switch (action.type) {
    case 'INCREMENT':
      return state + 1
    case 'INCREMENT_IF_ODD':
      return (state % 2 !== 0) ? state + 1 : state
    case 'DECREMENT':
      return state - 1
    default:
      return state
  }
}
saga/index.js
/* eslint-disable no-constant-condition */

import { put, takeEvery, delay } from 'redux-saga/effects'

export function* incrementAsync() {
  yield delay(1000)
  yield put({ type: 'INCREMENT' })
}

export default function* rootSaga() {
  yield takeEvery('INCREMENT_ASYNC', incrementAsync)
}
简单理解 ‘redux-saga/effects’ 中的几个关键字:fork,call, put,takeEvery,takeLatest,all
fork() 创建一个新的进程或者线程,并发发送请求
关键代码:

function* user() {
  yield takeEvery('FETCH_REQUEST', fetch_user); // 监听 FETCH_REQUEST action
}

// 并发发送请求
function* fetch_user() {
  const [users, todos] = [
    yield fork(fetchResource, 'https://jsonplaceholder.typicode.com/users'),
    yield fork(fetchResource, 'https://jsonplaceholder.typicode.com/todos')
  ]
}


function* fetchResource(resource) {
  const data = yield call(axios.get, resource);
  
  // 获取 call 数据,触发成功后的 action
  yield put({ type: 'FETCH_SUCESS', uu: data });
}
call() 发送 api 请求
put() 发送对应的 dispatch,触发对应的 action
takeEvery() 监听对应的 action 每一次 dispatch 都会触发

例如:点击一个新增的按钮,2s 后触发新增动作,在2s内不断点击按钮,这时候,每一次点击,都是有效的。
yield takeEvery(‘FETCH_USER’, fetch_user);
其中, FETCH_USER是action, fetch_user是监听到这个action后需要执行的动作。

takeLatest() 监听对应的 action只会触发最后一次 dispatch

例如:点击一个新增的按钮,2s 后触发新增动作,在2s内不断点击按钮,这时候,只有最后一次点击是有效的。
yield takeLatest(‘FETCH_USER’, fetch_user);
参数所指同takeEvery()

all() 跟 fork 一样,同时并发多个 action,没有顺序
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值