最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • redux-thunk、redux-saga、react-redux中间件的使用

    正文概述 掘金(落月誻雪)   2020-12-13   525

    demo源码: https://github.com/recall-lidemin/todolist-demo.git

    什么是Redux中间件?

    redux-thunk、redux-saga、react-redux中间件的使用

    • redux中间件的中间指的是action和store中间
    • redux中间件实际是对dispatch方法的封装或升级,升级之后,dispatch就既能接收对象,也能接收函数
    • 补充:中间件指的是redux的中间件,不是react的。

    1.redux-thunk

    • 安装redux-thunk yarn add redux-thunk
    • 注册中间件,使用applyMiddleware
    import { createStore, applyMiddleware, compose } from 'redux'
    import thunk from 'redux-thunk'
    import reducer from './reducer'
    
    // 为了thunk与devtools一起使用
    const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
     ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({})
     : compose
    const enhancer = composeEnhancers(applyMiddleware(thunk))
    const store = createStore(reducer, enhancer)
    
    export default store
    
    • 在action中使用,使用了redux-thunk中间件之后,action返回就可以是一个函数,不再必须是对象,在这个函数中,我们可以发起异步请求来获取数据,而且返回的函数会被注入dispatch这个参数,我们不再需要引入store
    store/actionCreators.js
    
    export const getTodoList = () => {
      return async (dispatch) => {
        const res = await axios.get('http://localhost:3000/list')
        const action = initListAction(res.data)
        dispatch(action)
      }
    }
    
    • 在页面组件中
    import {getTodoList} from './store/actionCreators'
    const TodoList = () => {
      // 发送请求获取数据
      const getList = async () => {
        const action = getTodoList()
        store.dispatch(action) // 注入dispatch
      }
    }
    

    2.redux-saga

    • 安装redux-saga yarn add redux-saga
    • 注册redux-saga
    import { createStore, applyMiddleware, compose } from 'redux'
    import createSagaMiddleware from 'redux-saga'
    import reducer from './reducer'
    import mySaga from './sagas'
    
    // 创建saga中间件
    const sagaMiddleware = createSagaMiddleware()
    // 开启devtools
    const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
      ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({})
      : compose
    // 注册saga
    const enhancer = composeEnhancers(applyMiddleware(sagaMiddleware))
    const store = createStore(reducer, enhancer)
    // 运行saga文件
    sagaMiddleware.run(mySaga)
    
    export default store
    
    • 在saga.js中使用
    import { call, put, takeEvery, takeLatest } from 'redux-saga/effects'
    import { GET_INIT_LIST } from './actionTypes'
    import { initListAction } from './actionCreators'
    import axios from 'axios'
    
    // 处理函数,可以在此进行异步请求,这里使用的es6的Genegetor函数
    function* fetchList() {
      try {
        const res = yield axios.get('http://localhost:3000/list')
        const action = initListAction(res.data)
        yield put(action)
      } catch (error) {
        // do null
      }
    }
    // 监听页面action的派发,执行对应的函数
    function* mySaga() {
      yield takeEvery(GET_INIT_LIST, fetchList)
    }
    
    export default mySaga
    
    • 在页面组件中分发,触发saga监听
      // 使用redux-saga
      const getList = async () => {
        const action = getTodoList()
        store.dispatch(action)
      }
    

    3.react-redux

    • 安装react-redux yarn add react-redux
    • 创建store
    import { createStore } from 'redux'
    import reducer from './reducers'
    
    const store = createStore(reducer)
    
    export default store
    
    • 连接react-redux,使用Provider,注册到上下文
    import React from 'react'
    import ReactDOM from 'react-dom'
    import 'antd/dist/antd.css'
    import TodoList from './todolist'
    import { Provider } from 'react-redux'
    import store from './react-redux'
    
    // react-redux连接store
    ReactDOM.render(
      <React.StrictMode>
        <Provider store={store}>
          <TodoList />
        </Provider>
      </React.StrictMode>,
      document.getElementById('root')
    
    • 在组件中通过connect使用
    import React from 'react'
    import { Button, Input, List } from 'antd'
    import { connect } from 'react-redux'
    
    const TodoList = (props) => {
      const { inputValue, list, handleChange, handleAdd, handleDel } = props
    
      return (
        <>
          <div style={{ display: 'flex' }}>
            <Input
              style={{ width: 200 }}
              value={inputValue}
              onChange={handleChange}
            />
            <Button type="primary" onClick={handleAdd}>
              提交
            </Button>
          </div>
          <List
            size="large"
            bordered
            dataSource={list}
            renderItem={(item, index) => (
              <List.Item key={item} onClick={() => handleDel(index)}>
                {item}
              </List.Item>
            )}
          />
        </>
      )
    }
    
    // 将state映射到props中
    const mapStateToProps = (state) => {
      return {
        inputValue: state.inputValue,
        list: state.list,
      }
    }
    // 将dispatch映射到props中,可以在此处写处理函数,也可以将dispatch从组件props中解构出来,直接在组件中进行dispatch分发,此处就可以不必写,只传一个mapStateToProps参数即可
    const mapDispatchToProps = (dispatch) => {
      return {
        handleChange(e) {
          dispatch({
            type: 'change_input_value',
            value: e.target.value,
          })
        },
        handleAdd() {
          dispatch({
            type: 'add_list',
          })
        },
        handleDel(index) {
          dispatch({
            type: 'del_list',
            value: index,
          })
        },
      }
    }
    
    export default connect(mapStateToProps, mapDispatchToProps)(TodoList)
    
    
    • 数据处理逻辑同样在reducer中

    起源地下载网 » redux-thunk、redux-saga、react-redux中间件的使用

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元