redux-thunk
redux中间件,处理异步请求.
actionCreators可以返回一个函数,在该函数里有参数dispatch,发送异步,异步成功之后分发action更改数据。
首先,通过 create-react-app app
创建app项目。
同步操作
- 第一步
安装:yarn add redux react-redux redux-thunk
- 第二步
在src
文件夹下创建store
文件夹,并创建入口文件index.js
,用来放store
在store
文件夹下创建reducers
文件夹,并创建文件articleReducer.js
,在articleReducer.js
中写如下代码:
//articleReducer.js
let initState = {
msg: 'article'
}
export default (state=initState ,action){
return state;//先不做具体操作,为后续操作做好准备工作
}
然后在reducers
文件夹中新建入口文件index.js
,作用是将多个reducer文件通过combineReducer
合并为一个reducer导出。
代码如下:
import article from './articleReducer';
import {combineReducers} from 'redux';
export default combineReducers({
//此处是可以对子reducer重命名的,使用时直接通过重命名的属性名调用即可
article: article
});
- 第三步
在store
文件夹的入口文件index.js
中写代码:
import {createStore} from 'redux';
import reducer from './reducers';
//window.__REDUX_DEVTOOLS_EXTENSION__ &&window.__REDUX_DEVTOOLS_EXTENSION__()是为了让dev-tools生效
let store = createStore(reducer,window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__());
export default store;
- 第四步
在src
文件夹下新建文件夹pages
,在pages
文件夹下新建文件Article.js
,在其中写入代码:
import React, { Component } from 'react';
import { connect } from 'react-redux';
class Article extends Component {
render() {
return (
<div>
{JSON.stringify(this.props)}
<button onClick={this.props.changeMsg}>修改msg</button>
</div>
)
}
}
const mapStateToProps = (state, ownProps) => {
return state;
}
const mapDispatchToProps = (dispatch, ownProps) => {
return {
changeMsg: () => {
//这里我们将msg中的内容修改为123
dispatch(changeMsg('123'));
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Article);
- 第五步
在store
文件夹下新建文件actionTypes.js
,写入代码:
export const CHANGE_MSG = 'CHANGE_MSG';
在store
文件夹中新建文件夹actionCreators
,并新建文件actionArticle.js
,写入代码:
import { CHANGE_MSG } from '../actionTypes';
export const changeMsg = (value) => {
return {
type: CHANGE_MSG,
value
}
}
- 第六步
在第一步的articleReducer.js
文件中添加如下代码:
+ import { CHANGE_MSG } from '../actionTypes';
let initState = {
msg: 'article',
}
export default (state = initState, action) => {
+if (action.type === CHANGE_MSG) {
+ return {
+ ...state,
+ msg: action.value
+ }
+}
return state;
}
- 第七步:
在src
目录下的App.js
文件中引入模块Article.js
,代码如下:
import React from 'react';
// import logo from './logo.svg';
import './App.css';
import Article from './pages/Article';
function App() {
return (
<div>
<Article></Article>
</div>
);
}
export default App;
- 第八步
在src
目录下的index.js
文件中引入Provider,引入store,然后使用,代码如下:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
+ import { Provider } from 'react-redux';
+ import store from './store';
+ ReactDOM.render(<Provider store={store}><App /></Provider>, document.getElementById('root'));
serviceWorker.unregister();
演示:
点击后:
同步修改数据成功!
异步操作
在上面的代码基础上进行修改。
- 第一步
在Article.js
文件中修改如下:
import React, { Component } from 'react';
import { connect } from 'react-redux';
+ import { changeMsg, getDataAxAction } from '../store/actionCreator/articleAction';
class Article extends Component {
render() {
return (
<div>
{JSON.stringify(this.props)}
<button onClick={this.props.changeMsg}>修改msg</button>
+ <button onClick={this.props.getData}>获取异步数据</button>
</div>
)
}
}
const mapStateToProps = (state, ownProps) => {
return state;
}
const mapDispatchToProps = (dispatch, ownProps) => {
return {
changeMsg: () => {
dispatch(changeMsg('111'))
},
+ getData: () => {
+ dispatch(getDataAxAction({
+ page: 0, pageSize: 10
+ }));
+ }
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Article);
- 第二步,在
articleReducer.js
中修改如下:
+ import { CHANGE_MSG, CHANGE_ARTICLES } from '../actionTypes';
let initState = {
msg: 'article',
+ articles: []
}
export default (state = initState, action) => {
if (action.type === CHANGE_MSG) {
return {
...state,
msg: action.value
}
}
+ if (action.type === CHANGE_ARTICLES) {
+ return {
+ ...state,
+ articles: action.value
+ }
+ }
return state;
}
在actionTypes.js
中添加一条语句:
export const CHANGE_ARTICLES = 'CHANGE_ARTICLES';
- 第三步,安装 axios
yarn add axios
- 第四步,在
articleAction.js
中修改如下,获取异步数据:
import { CHANGE_MSG, CHANGE_ARTICLES } from '../actionTypes';
import axios from 'axios';
export const changeMsg = (value) => {
return {
type: CHANGE_MSG,
value
}
}
export const getDataAxAction = (value) => {
return (dispatch) => {
axios.get('http://134.175.154.93/manager/article/findArticle', { params: value }).then((res) => {
dispatch(changeArticles(res.data.data.list))
}).catch((err) => {
console.log(err)
})
}
}
const changeArticles = (value) => {
return {
type: CHANGE_ARTICLES,
value
}
}
- 第五步,在
store
的入口文件index.js
中修改如下:
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk'
import reducer from './reducers';
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose;
const enhancer = composeEnhancers(applyMiddleware(thunk))
// let store = createStore(reducer, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__())
let store = createStore(
reducer,
enhancer
//如果不想使用dev-tools工具,可以用下面这个代替,并且上面相关操作也可以省略
//applyMiddleware(thunk)
);
export default store;
测试:
点击获取异步数据按钮后:
异步获取数据成功!