Redux异步操作redux-thunk

时间:2022-12-28 10:35:41

用户发出 Action,Reducer 函数算出新的 State,View 重新渲染。但是,一个关键问题没有解决:异步操作怎么办?Action 发出以后,Reducer 立即算出 State,这叫做同步;Action 发出以后,过一段时间再执行 Reducer,这就是异步
怎么才能 Reducer 在异步操作结束后自动执行呢?这就要用到新的工具:中间件(middleware)。

Github:https://github.com/gaearon/redux-thunk

一.redux-thunk

redux-thunk 是一个比较流行的 redux 异步 action 中间件,比如 action 中有 ****setTimeout**** 或者通过 ****fetch****通用远程 API 这些场景,那么久应该使用 redux-thunk 了。redux-thunk 帮助你统一了异步和同步 action 的调用方式,把异步过程放在 action 级别解决,对 component 没有影响。

1.中间件的概念

如果要添加功能,你会在哪个环节添加?

(1)Reducer:纯函数,只承担计算 State 的功能,不合适承担其他功能,也承担不了,因为理论上,纯函数不能进行读写操作。
(2)View:与 State 一一对应,可以看作 State 的视觉层,也不合适承担其他功能。
(3)Action:存放数据的对象,即消息的载体,只能被别人操作,自己不能进行任何操作。

想来想去,只有发送 Action 的这个步骤,即store.dispatch()方法,可以添加功能。举例来说,要添加日志功能,把 Action 和 State 打印出来,可以对store.dispatch进行如下改造。

let next = store.dispatch;
store.dispatch = function dispatchAndLog(action) {
  console.log('dispatching', action);
  next(action);
  console.log('next state', store.getState());
}

上面代码中,对store.dispatch进行了重定义,在发送 Action 前后添加了打印功能。这就是中间件的雏形。

中间件就是一个函数,对store.dispatch方法进行了改造,在发出 Action 和执行 Reducer 这两步之间,添加了其他功能

二.例子

从上一篇:Redux基本语法 机关枪的例子

这边补充异步的操作:

index.redux.js

//延迟添加 拖俩天再给
export  function addGunAsync(){
	//thunk插件的作用,这里可以返回函数
	return dispatch =>{
		//异步结束后,手动执行dispatch
		setTimeout(() => {
		  	dispatch(addGUN())
		}, 2000)
	}
}

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import { createStore ,applyMiddleware} from 'redux'; 
import thunk from 'redux-thunk'; 
import {counter,addGUN,removeGUN,addGunAsync} from './index.redux';

//1.新建store
const store = createStore(counter,applyMiddleware(thunk));


function render() {
	//reactDOM 渲染页面
   //2.这个store 以在组件属性props传给Component 组件
	ReactDOM.render(<App store={store} addGunAsync={addGunAsync} addGUN={addGUN} removeGUN={removeGUN} />, document.getElementById('root'));
	registerServiceWorker();
}
render();
//3.以subscribe订阅render的函数 这样我们可以知道state的变化
store.subscribe(render);

app.js

import React from 'react';

class App extends React.Component {
	render() {
		//4.通过组件的属性props 获取store以及数据操作addGUN
		//5.在通过dispatch(addGUN()) 发送action
		const store=this.props.store;
		const num =store.getState();
		const addGUN=this.props.addGUN;
		const removeGUN=this.props.removeGUN;
		const addGunAsync=this.props.addGunAsync;
		return (
			<div>
				<h1>现在有机枪{num}把</h1>
				<button onClick={()=>store.dispatch(addGUN())}>申请武器</button>
				<button onClick={()=>store.dispatch(removeGUN())}>上交武器</button>
				<button onClick={()=>store.dispatch(addGunAsync())}>拖2天上交武器</button>
			</div>
		);
	}
}

export default App;

Redux异步操作redux-thunk

点击拖2天上交武器按钮  过2秒后 会自动加1把机关枪 ,这就是异步操作。