redux-saga中间件的使用

公众号:CS阿吉

异步处理两种方式:redux-thunk,redux-saga(适用于特别大型的项目)

先展示redux-thunk:

todulist.js
//这个算是redux进阶的Demo
import React, { Component } from "react";
import store from "../../store";
import {
  getInputChangeValue,
  getAddItemAction,
  getDeleteItemAction,
  initListAction,
  getTodoList
} from "../../store/actionCreaters";
import ToDoListUI from './ToDoListUI';

class ToDoListUp extends Component {
  constructor(props) {
    super(props);
    this.state = store.getState();
    this.handleInputChange = this.handleInputChange.bind(this);
    this.handleStoreChange = this.handleStoreChange.bind(this);
    this.handleButtonClick = this.handleButtonClick.bind(this);
    /**
     * 页面上的内容并没有随着store的更新而更新,所以如下操作:
     * store发生改变,则subscribe()绑定的函数会自动执行
     */
    store.subscribe(this.handleStoreChange);
  }

  componentDidMount() {
      const action = getTodoList();
    //   当调用store.dispatch把action发给store的时候,action会自动执行。
      store.dispatch(action);
  }

  // input值改变触发action
  handleInputChange(e) {
    //定义action两种方式,下面是最原始的一种:(1)
    // const action = {
    //   type: CHANGE_INPUT_VALUE,
    //   value: e.target.value
    // };
    //下面是改进的方式:(2)
    const action = getInputChangeValue(e.target.value);
    store.dispatch(action);

    console.log(e.target.value);
  }
  // 重新渲染页面数据
  handleStoreChange() {
    this.setState(store.getState());
  }
  // 提交输入内容
  handleButtonClick() {
    const action = getAddItemAction();

    store.dispatch(action);
  }
  // 点击列表电影名字,会删除电影
  handleItemDelete(index) {
    const action = getDeleteItemAction(index);
    store.dispatch(action);
  }

  render() {
    return (
      <ToDoListUI
        list={this.state.list}
        inputValue={this.state.inputValue}
        handleInputChange={this.handleInputChange}
        handleButtonClick={this.handleButtonClick}
        handleItemDelete={this.handleItemDelete}
      />
    );
  }
}

export default ToDoListUp;

store.js
import { createStore, applyMiddleware, compose } from "redux";
import reducer from './reducer';
import thunk from "redux-thunk";

/**
 * 在创建store的时候使用reducer构建初始数据
 * 在创建的时候会使用thunk和__REDUX_DEVTOOLS_EXTENSION__ 中间件
 * 这里的中间件指的是redux的中间件,而不是react
 * 
 */
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
    ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({})
    : compose;

const enhancer = composeEnhancers(
  applyMiddleware(thunk)
  // other store enhancers if any
);

const store = createStore(reducer, enhancer);

export default store;

actionType.js
import {
  CHANGE_INPUT_VALUE,
  ADD_TODO_ITEM,
  DELETE_TODO_ITEM,
  INIT_LIST_ACTION
} from "./actionTypes";
import axios from 'axios';

export const getInputChangeValue = (value) => ({
        type: CHANGE_INPUT_VALUE,
        value:value
});

export const getAddItemAction = () => ({
         type: ADD_TODO_ITEM,
});

export const getDeleteItemAction = (index) => ({
         type: DELETE_TODO_ITEM,
         index
});

export const initListAction = (data) => ({
         type: INIT_LIST_ACTION,
         data
});

export const getTodoList = () => {
  return (dispatch) => {
    axios("http://localhost:3000/mock/list.json")
      .then(res => {
        const data = res.data;
        // 改变store中的数据
        const action = initListAction(data);
        dispatch(action);
      })
      .catch(err => {
        console.log(err);
      });
  }
};

下面开始react-saga的使用:

store.js
import { createStore, applyMiddleware, compose } from "redux";
import reducer from './reducer';
import thunk from "redux-thunk";
import createSagaMiddleware from "redux-saga";


/**
 * 在创建store的时候使用reducer构建初始数据
 * 在创建的时候会使用thunk和__REDUX_DEVTOOLS_EXTENSION__ 中间件
 * 这里的中间件指的是redux的中间件,而不是react
 * 
 */
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
    ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({})
    : compose;

// create the saga middleware
const sagaMiddleware = createSagaMiddleware()

const enhancer = composeEnhancers(applyMiddleware(sagaMiddleware));


const store = createStore(reducer, enhancer);

export default store;

//新建一个saga.js文件
import { takeEvery,put } from "redux-saga/effects";
import {GET_INIT_LIST} from './actionTypes';
import {initListAction} from './actionCreaters';
import axios from 'axios';

function* getInitList(){
    try{
        const res = yield axios.get("http://localhost:3000/mock/list.json");
        const action = initListAction(res.data);
        yield put(action);
    }catch(e){
        console.log("网络请求失败");
    }
}

//generator函数
function* todoSagas(){
    yield takeEvery(GET_INIT_LIST, getInitList);
}

export default todoSagas;

store.js
import { createStore, applyMiddleware, compose } from "redux";
import reducer from './reducer';
import thunk from "redux-thunk";
import createSagaMiddleware from "redux-saga";
import todoSagas from './saga';


/**
 * 在创建store的时候使用reducer构建初始数据
 * 在创建的时候会使用thunk和__REDUX_DEVTOOLS_EXTENSION__ 中间件
 * 这里的中间件指的是redux的中间件,而不是react
 * 
 */
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
    ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({})
    : compose;

// create the saga middleware
const sagaMiddleware = createSagaMiddleware()

const enhancer = composeEnhancers(applyMiddleware(sagaMiddleware));

const store = createStore(reducer, enhancer);

// then run the saga
sagaMiddleware.run(todoSagas);

// render the application

export default store;

todolist.js
//这个算是redux进阶的Demo
import React, { Component } from "react";
import store from "../../store";
import {
  getInputChangeValue,
  getAddItemAction,
  getDeleteItemAction,
  initListAction,
  getInitList
  
} from "../../store/actionCreaters";
import ToDoListUI from './ToDoListUI';
import axios from 'axios';

class ToDoListUp extends Component {
  constructor(props) {
    super(props);
    this.state = store.getState();
    this.handleInputChange = this.handleInputChange.bind(this);
    this.handleStoreChange = this.handleStoreChange.bind(this);
    this.handleButtonClick = this.handleButtonClick.bind(this);
    /**
     * 页面上的内容并没有随着store的更新而更新,所以如下操作:
     * store发生改变,则subscribe()绑定的函数会自动执行
     */
    store.subscribe(this.handleStoreChange);
  }

  componentDidMount() {
    const action = getInitList();
    store.dispatch(action);
    console.log(action);
  }

  // input值改变触发action
  handleInputChange(e) {
    //定义action两种方式,下面是最原始的一种:(1)
    // const action = {
    //   type: CHANGE_INPUT_VALUE,
    //   value: e.target.value
    // };
    //下面是改进的方式:(2)
    const action = getInputChangeValue(e.target.value);
    store.dispatch(action);

    console.log(e.target.value);
  }
  // 重新渲染页面数据
  handleStoreChange() {
    this.setState(store.getState());
  }
  // 提交输入内容
  handleButtonClick() {
    const action = getAddItemAction();

    store.dispatch(action);
  }
  // 点击列表电影名字,会删除电影
  handleItemDelete(index) {
    const action = getDeleteItemAction(index);
    store.dispatch(action);
  }

  render() {
    return (
      <ToDoListUI
        list={this.state.list}
        inputValue={this.state.inputValue}
        handleInputChange={this.handleInputChange}
        handleButtonClick={this.handleButtonClick}
        handleItemDelete={this.handleItemDelete}
      />
    );
  }
}

export default ToDoListUp;

actionType.js'
export const CHANGE_INPUT_VALUE = 'change_input_value';
export const ADD_TODO_ITEM = 'add_todo_item';
export const DELETE_TODO_ITEM = 'delete_todo_item';
export const INIT_LIST_ACTION = "init_list_action";
export const GET_INIT_LIST = "get_init_list";

actionCreator.js
import {
  CHANGE_INPUT_VALUE,
  ADD_TODO_ITEM,
  DELETE_TODO_ITEM,
  INIT_LIST_ACTION,
  GET_INIT_LIST
} from "./actionTypes";
import axios from 'axios';

export const getInputChangeValue = (value) => ({
        type: CHANGE_INPUT_VALUE,
        value:value
});

export const getAddItemAction = () => ({
         type: ADD_TODO_ITEM,
});

export const getDeleteItemAction = (index) => ({
         type: DELETE_TODO_ITEM,
         index
});

export const initListAction = (data) => ({
         type: INIT_LIST_ACTION,
         data
});

export const getInitList = () => ({
  type:GET_INIT_LIST
})

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值