上片文章,如果把一些复杂逻辑或者异步请求,放在同一个组件中,会显得冗长和难以管理。
我们可以使用react-thunk这个中间件进行管理。
可以把逻辑放在action中
优势:自动化测试特别方便
首先,学会使用:
redux-thunk
Installation
npm install redux-thunk
Then, to enable Redux Thunk, use applyMiddleware():
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers/index';
// Note: this API requires redux@>=3.1.0
const store = createStore(
rootReducer,
applyMiddleware(thunk)
);
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
这个是redux devtools的 插件的使用的代码,要带上
如果只是使用thunk插件,那就:
import {createStore,applyMiddleware} from 'redux';
import reducer from './reducer';
import thunk from "redux-thunk";
/**
* 在创建store的时候使用reducer构建初始数据
* 在创建的时候会使用thunk和__REDUX_DEVTOOLS_EXTENSION__ 中间件
* 这里的中间件指的是redux的中间件,而不是react
*
*/
const store = createStore(reducer, applyMiddleware(thunk));
export default store;
如果使用thunk和redux devtools插件,那就
redux-devtools-extension
1.2 Advanced store setup
If you setup your store with middleware and enhancers, change:
import { createStore, applyMiddleware, compose } from 'redux';
+ const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
+ const store = createStore(reducer, /* preloadedState, */ composeEnhancers(
- const store = createStore(reducer, /* preloadedState, */ compose(
applyMiddleware(...middleware)
));
const composeEnhancers =
typeof window === 'object' &&
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
// Specify extension’s options like name, actionsBlacklist, actionsCreators, serialize...
}) : compose;
const enhancer = composeEnhancers(
applyMiddleware(...middleware),
// other store enhancers if any
);
const store = createStore(reducer, enhancer);
实际上配置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;
然后我们修改todolist组件中的代码,我们可以把componentDidMount中的代码移除,移动到action中去。
*当时候redux-thunk之后,我们当action可以是一个函数了。
修改如下:
actionCreaters.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);
});
}
};
因为在配置文件中我已经配置了axios的原型链,正常的话使用是this.axios就可以使用了。但是在这里不知道为啥子不好用,就采用常规办法吧。
修改todolist.js
核心代码:
componentDidMount() {
const action = getTodoList();
// 当调用store.dispatch把action发给store的时候,action会自动执行。
store.dispatch(action);
console.log(action);
}
//这个算是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);
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;