redux结合saga

img

redux

1.action

State 的变化,会导致 View 的变化。但是,用户接触不到 State,只能接触到 View。所以,State 的变化必须是 View 导致的。Action 就是 View 发出的通知,表示 State 应该要发生变化了。

Action 是一个对象。其中的type属性是必须的,表示 Action 的名称。其他属性可以自由设置,社区有一个规范可以参考。

const action = {
  type: 'ADD_TODO',
  payload: 'Learn Redux'
};

2.action creator

View 要发送多少种消息,就会有多少种 Action。如果都手写,会很麻烦。可以定义一个函数来生成 Action,这个函数就叫 Action Creator。

import { GETLIST } from "./actionTypes";

export const getlist = () => {
  return {
    type:GETLIST
  }
}

3.state

Store对象包含所有数据。如果想得到某个时点的数据,就要对 Store 生成快照。这种时点的数据集合,就叫做 State。

当前时刻的 State,可以通过store.getState()拿到

import { applyMiddleware,createStore } from "redux";
import { Map } from 'immutable'
import reducer from "./reducer";

import createSagaMiddleware from 'redux-saga'
import sagas from './sagas'

const sagaMiddleware = createSagaMiddleware()

const store =  createStore(
  reducer,
  Map([]),
  applyMiddleware(sagaMiddleware)
)

sagas.forEach(saga => sagaMiddleware.run(saga))

export default store

4.Reducer

Store 收到 Action 以后,必须给出一个新的 State,这样 View 才会发生变化。这种 State 的计算过程就叫做 Reducer。

import { Map,List } from 'immutable'
import { LOADLIST } from './actionTypes'

const defaultState = Map({
  doclist:List([])
})

export default (state = defaultState , action) => {
  switch(action.type){
    case LOADLIST:
      return state.updateIn(['doclist'],()=>action.doclist)
    default:
      return state
  }
}

5. store.dispatch()

store.dispatch()是 View 发出 Action 的唯一方法

import React,{ useEffect } from 'react'
import Swiper2 from './Swiper2'
// import Swiper3 from './Swiper3'
import FindDoctorContainerUi from './FindDoctorContainerUi'
import { useDispatch } from 'react-redux'
import { getlist } from '../index'
import { useSelector } from 'react-redux'
import { FindDoctorMainWrapper } from './styledFindDoctorContainer'

export default function FindDoctorContainer() {
  const dispatch = useDispatch()
  const docList = useSelector(state => state.getIn(['findDoc','doclist']))

  useEffect( () => {
    dispatch(getlist())
  },[])



  return (
        <FindDoctorContainerUi doclist={docList}></FindDoctorContainerUi>
  )
}

6.sagas

用于异步请求数据

sagas里面的一些参数:

​ fork:创建一个新的进程或者线程并发请求

​ call:发送api请求

​ put:发送对应的dispatch,触发对应的action

​ takeEvery:监听对应的action,每已次dispatch都会触发

​ takeLatest:监听对应的action,只会触发最后一次dispatch(触发一次动作后,又不断的触发动作,在一定的时间内。只有最后一次触发有效)

​ call:和fork一样同时发出多个action

import $http from '@/utils/http'
import { put, takeEvery, call } from 'redux-saga/effects'
import { GETLIST, LOADLIST } from './actionTypes'

function* foo2(){
 
  let result = yield call($http.get, {
    url:'http://localhost:9000/docList'
  })

  yield put({
    type: LOADLIST,
    doclist:result.data.data
  })
}

function* saga(){
  yield takeEvery(GETLIST, foo2)
}
export default saga

主要api

createStore(reducer,[preloadStore], enhancer)

Store

combineReducers(reducers)

applyMiddleware(…middlewares)

bindActionCreators

compose

redux-saga/effects

1.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 });
}
2.call

发送api请求

3.put

发送对应的dispatch并触发action

4.takeEvery

监听对应的 action;
每一次 dispatch 都会触发;例如:点击一个新增的按钮,2s 后触发新增动作,在2s内不断点击按钮,这时候,每一次点击,都是有效的。

5.takeLatest

监听对应的 action;
只会触发最后一次 dispatch;例如:点击一个新增的按钮,2s 后触发新增动作,在2s内不断点击按钮,这时候,只有最后一次点击是有效的。

6.all

跟 fork 一样,同时并发多个 action,没有顺序。

const rootUser = [
    user(),
    todo()
];

yield all([ // 同时并发多个
    ...rootUser, // 
    add()
]);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值