公众号: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
})