使用Redux-thunk中间件进行ajax请求发送
什么是Redux中间件
- 中间件:程序执行过程中,加入的附件,用来处理数据、流程、对象等操作。
- Redux中间件指的是Action与Store之间。之前,在Redux中Action只能是一个对象,Action以对象的形式直接派发给了Store,但是现在我们使用了Redux-thunk之后,Action可以是函数了。变成函数的原因如下图,Action通过dispatch方法传递给了Store,因此dispatch就是Action和Store中间的部分,实际上该中间件就是对dispatch的封装和升级。当没有中间件时,是dispatch接收到一个Action的对象把对象传递给Stroe。当有了中间件时,如果Action传输的是一个函数的话,会先将函数执行将函数结果转换成对象传输给Store。
安装
使用
- 使用了redux-thunk后在action部分不仅可以返回函数,还可以返回对象。
| import { createStore, applyMiddleware } from 'redux'
import thunk from 'redux-thunk'
import rootReducer from './reducers/index'
const store = createStore(rootReducer, applyMiddleware(thunk))
|
代码示例
| import React, { Component } from "react";
import store from "./store";
import { getTodoList } from "./store/actionCreators";
import TodoListUI from './TodoListUI';
class TodoList extends Component {
// 构造方法,固定接收props
constructor(props) {
// 当props发生改变,render就会被重新执行
// 当父组件的render函数被运行时,它的子组件的render都将被重新运行
// 调用父类的构造函数
super(props);
this.state = store.getState()
this.handleInputChange = this.handleInputChange.bind(this)
this.handleStoreChange = this.handleStoreChange.bind(this)
this.handleBtnClick = this.handleBtnClick.bind(this)
this.handleItemDelete = this.handleItemDelete.bind(this)
// 自动订阅store,监听store的内容
store.subscribe(this.handleStoreChange);
}
render() {
return <TodoListUI
inputValue={this.state.inputValue}
handleInputChange={this.handleInputChange}
handleBtnClick={this.handleBtnClick}
list={this.state.list}
handleItemDelete={this.handleItemDelete}
/>
}
componentDidMount () {
const action = getTodoList();
/*
console.log('action', action)
action () => {
axios__WEBPACK_IMPORTED_MODULE_1__["default"].get('http://e.com/api/index/index').then(res => {
const data = res.data;
console.log(data);
// const action = initListActio…
*/
store.dispatch(action);
}
handleInputChange(e) {
const value = e.target.value;
const action = {
type: 'change_input_value',
value: value
}
store.dispatch(action);
}
handleStoreChange () {
this.setState(store.getState())
}
handleBtnClick() {
const value = this.state.inputValue
const action = {
type: 'change_child_value',
value: value
}
store.dispatch(action);
}
handleItemDelete(index) {
const action = {
type: 'del_child_value',
index: index
}
console.log(action)
store.dispatch(action)
}
}
export default TodoList
|
| import axios from 'axios';
import { INIT_LIST_ACTION } from './actionTypes';
export const initListAction = (data) => ({
type: INIT_LIST_ACTION,
data
})
export const getTodoList = () => {
return (dispatch) => {
axios.get('http://e.com/api/index/index')
.then((res) => {
const data = res.data;
const action = initListAction(data);
dispatch(action);
})
.catch(() => {
alert('error')
})
}
}
|
| import React, { Component, Fragment } from "react";
import TodoItem from "./TodoItem";
import './style.css'
class TodoListUI extends Component {
render () {
return (
<Fragment>
<div>
<label htmlFor="insertArea">输入内容</label>
<input
id="insertArea"
className="input"
value={this.props.inputValue}
onChange={this.props.handleInputChange}
/>
<button onClick={this.props.handleBtnClick}>提交</button>
</div>
<ul>
{
// 渲染数据
this.props.list.map((item, index) => {
return (
<TodoItem
itemVal={item}
index={index}
del={this.props.handleItemDelete}
/>
)
})
}
</ul>
</Fragment>
)
}
}
export default TodoListUI;
|
| // 定义在reducer只有两个字段,后续传入到store store也就知道reducer存储内容的结构了
const defaultState = {
inputValue: '',
list: [],
index: '',
}
// state = defaultState 默认什么都不存储
// reducer 可以接收state,但是绝不能修改state
export default (state = defaultState, action) => {
// console.log(state, action)
/*
{inputValue: '', list: Array(0)}]:
{type: 'change_input_value', value: 'f'}
*/
if (action.type === 'change_input_value') {
// 执行一次深拷贝 然后修改深拷贝的值
const newState = JSON.parse(JSON.stringify(state));
newState.inputValue = action.value;
return newState;
}
if (action.type === 'change_child_value') {
const newState = JSON.parse(JSON.stringify(state));
newState.list.push(newState.inputValue);
newState.inputValue = '';
console.log('change_child_value:newState', newState)
/**
{
inputValue: ""
list: ['123', '321']
}
*/
return newState;
}
if (action.type === 'del_child_value') {
const newState = JSON.parse(JSON.stringify(state))
console.log(newState)
// console.log(newState, state)
newState.list.splice(action.index, 1);
return newState;
}
if (action.type === 'init_list_action') {
const newState = JSON.parse(JSON.stringify(state))
newState.list = action.data;
return newState;
}
// state: 整个store存储的数据
return state
}
|