携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情
redux---redux-thunk:异步action插件(解决redux里的action中复杂的数据类型,也就是解决异步处理的)
redux里所有的action都必须是一个简单地数据类型
比较复杂的话,就需要借助一个插件 redux-thunk
这个插件是用来解决异步处理的
安装: npm i redux-thunk
redux-thunk是redux里最知名的插件
承接前几篇文章的代码描述
/store/index.js
import { createStore, compose, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import rootReducer from "./reducers";
// 使用了redux-thunk插件之后可以返回一个function作为dispatch的参数
// 作用:判断当前action是什么
// 如果是一个function那么会自动的把dispatch当参数传递到function内部
// 否则直接dispatch
const store = createStore(
rootReducer,
// compose 类似于把多个插件合并成一个
// applyMiddleware允许使用这个中间件
compose(
applyMiddleware(...[thunk]),
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
)
); // 创建一个store
export default store;
/store/actions/counter.js
export function addAction(step) {
return {
type: "ADD",
payload: {
step,
},
};
}
export const reduceAction = (step) => ({
type: "REDUCE",
payload: {
step,
},
});
// 使用了redux-thunk插件之后可以返回一个function作为dispatch的参数
// 作用:判断当前action是什么
// 如果是一个function那么会自动的把dispatch当参数传递到function内部
// 否则直接dispatch
/* export function asyncAdd(step) {
return function (dispatch) {
setTimeout(function () {
dispatch({
type: "ADD",
payload: {
step,
},
});
}, 1000);
};
} */
// 另一种写法
export const asyncAdd = (step) => (dispatch) => {
setTimeout(() => {
dispatch({
type: "ADD",
payload: {
step,
},
});
}, 1000);
};
react---redux-thunk 有异步action和接口配合使用
/src/api/movies.js 封装接口
export function loadMovies() {
return fetch(
"https://pcw-api.iqiyi.com/search/recommend/list?channel_id=4&data_type=1&mode=24&page_id=1&ret_num=48"
).then((res) => res.json());
}
/src/store/actions/product.js dispatch派送内容的封装
import { loadMovies } from "../../api/movies";
export const loaDataAction = () => async (dispatch) => {
const res = await loadMovies();
dispatch({
type: "LOAD_DATA_END",
payload: res.data.list,
});
// loadMovies().then((res) => {
// console.log(res);
// dispatch({
// type: "LOAD_DATA_END",
// payload: res.data.list,
// });
// });
};
/src/store/reducers/product.js 定意思一个product的reducer
export default function product(state = { list: [], page: 1 }, action) {
// console.group("product reducer");
// console.log(state);
// console.log(action);
// console.groupEnd();
switch (action.type) {
case "LOAD_DATA_END":
return { ...state, list: action.payload };
default:
return state;
}
}
/src/component/Movies.jsx 页面
import React, { Component } from "react";
import { connect } from "react-redux";
class Movies extends Component {
render() {
return <div>{this.props.list.length}</div>;
}
}
export default connect((state) => state.product)(Movies); //函数返回的是啥 上面的props就是啥
/src/App.js 引入redux中的数据
import React from "react";
import { connect } from "react-redux";
import logo from "./logo.svg";
import "./App.css";
import Counter from "./components/Counter";
import Movies from "./components/Movies";
import { addAction, reduceAction, asyncAdd } from "./store/actions/counter";
import { loaDataAction } from "./store/actions/product";
function App(props) {
console.log(props);
const { count, dispatch } = props;
return (
<div className="App">
<h1>{count}</h1>
<button onClick={() => dispatch(addAction(5))}>加</button>
<button onClick={() => dispatch(reduceAction(1))}>减</button>
<button onClick={() => dispatch(asyncAdd(1))}>异步加</button>
<Counter />
<Movies />
<button
onClick={() => {
dispatch(loaDataAction());
}}
>
加载数据
</button>
</div>
);
}
// state表示所有的数据
function mapStateToProps(state) {
return state.counter;
}
// 通过connect可以把redux中的state数据和dispatch方法映射到组件的属性中
// export default connect(mapStateToProps)(App);
export default connect((state) => state.counter)(App);