React書城小案例
阿新 • • 發佈:2018-12-12
步驟1:api介面設定
- api下的index.js 處理axios的公共部分
import axios from 'axios'; import qs from 'qs'; axios.defaults.baseURL = "http://localhost:8000"; axios.defaults.withCredentials = true; axios.interceptors.response.use(res=>res.data); axios.defaults.transformRequest=data=>qs.stringify(data); export default axios;
步驟2 通過axios 設定好獲取資料的方法
import axios from 'index.js'; const getBanner =()=>{ return axios.get("/course/banner") }; let initParams = {limit:10,page:1,type:"all"}; const getCourseList = (params=initParams)=>{ return axios.get("/course/list",{params}) }; const getCourseInfo = (courseID)=>{ return axios.get("/course/info",{params:{courseID}}) }; export {getBanner,getCourseList,getCourseInfo}
步驟3: 使用設定好的axios方法 處理action
import * as Types from "../action-types"; import {getBanner,getCourseList} from "../../api/course"; //定義actionCreator方法 let courseBanner = ()=>{ return async (dispatch)=>{ //使用了redux-thunk中介軟體 async await是對非同步的同步呼叫的簡化 let {data} = await getBanner(); dispatch({type:Types.COURSE_BANNER,data}) } }; let courseList = (params={},replace=true)=>{ params={ limit:10, page:1, type:"all", ...params }; return async (dispatch)=>{ let result = await getCourseList(params); dispatch({type:Types.COURSE_LIST,result,courseType:params.type,replace}); } }; let courseLoading = ()=>{ return {type:Types.COURSE_ISLOADING} }; export {courseBanner,courseList,courseLoading};
步驟4: 通過redux-aciotn中的handleActions處理reducer
//例子:
let course = handleActions({
[Types.COURSE_BANNER]:(state,action)=>{
return {...state,bannerData:action.data}
}
})
- action中dispatch派發的物件就是reducer中的action
import * as Types from "../action-types";
import {handleActions} from "redux-actions";
let initState = {
bannerData:[],
courseData:[],
courseType:"all",
replace: true, //若為true表示篩選替換資料,若為false則表示追加資料
isLoading: false
};
let course = handleActions({
[Types.COURSE_BANNER]:(state,action)=>{
return {...state,bannerData:action.data}
},
[Types.COURSE_LIST]:(state,action)=>{
let {result,courseType,replace} = action;
if(replace){
return {...state,courseData:result.data,courseType,total:result.total,page:result.page};
}else{
let combineData = [].concat(state.courseData,result.data);//老的資料和新的資料合併在一起
return {...state,courseData:combineData,courseType,total:result.total,page:result.page,isLoading:false};
}
},
[Types.COURSE_ISLOADING]:(state,action)=>{
return {...state,isLoading: true}
}
},initState);
export default course;
步驟5:通過store下的index.js 匯出需要store
import {combineReducers} from 'redux';
import course from './course';
let reducer = combineReducers({
course,
});
export default reducer;
步驟6:去到對應的元件進行操作
import React from "react";
import {connect} from "react-redux";
import {NavLink} from 'react-router-dom';
import { Carousel,Icon,Alert,Button } from 'antd';
import "./course.less";
import actions from "../../store/action";
class Course extends React.Component{
componentWillMount(){
if(this.props.bannerData.length<=0){
this.props.courseBanner(); //派發指令拿到資料
}
if(this.props.courseData.length<=0){
this.props.courseList();
}
//在元件渲染之前 獲取相應的資料 例:輪播圖資料和課程資料
}
render(){
console.log(this.props);//打印出上圖中的資料 ,拿到資料後進行相應操作,後面的事就差不多了
let {bannerData,courseData,courseType,total,page,courseList,isLoading,courseLoading} = this.props;
return <div className="courseBox">
{
bannerData.length>0?<Carousel autoplay>
{
bannerData.map((item,index)=>{
return <div key={index}>
<img src={item.pic} alt="" onClick={(e)=>{
let type = item.type;
this.props.courseList({type});}}
/>
</div>
})
}
</Carousel>:null
}
<div className="couBox">
<h2><Icon type="menu-fold"/><span>
{courseType==="all"?'全部課程':courseType==="react"?
'REACT課程':courseType==="vue"?'VUE課程':"小程式課程"}
</span></h2>
<div className="courseList">
{
courseData.length>0?
courseData.map(function(item,index){
let {name,dec,pic,time,id}=item;
return <div className="couItem" key={index}>
<NavLink to={{
pathname:'/course/info',
search:`courseID=${id}`
}}>
<h3 className="title">{name}</h3>
<div className="desc">
<div className="imgBox">
<img src={pic} alt=""/>
</div>
<p>{dec}</p>
<span>時間:{time}</span>
</div>
</NavLink>
</div>}) :<Alert message="Warning Text" type="Warning" description="當前沒有資料"/>
}
{isLoading?<Button type="primary" loading className="loading">
載入中
</Button>:total<=page?null:
<a href="###" className="loadMore" onClick={(e)=>{
courseLoading();
courseList({
page:parseInt(page)+1,
type:courseType
},false)
}}><Button type="dashed">載入更多</Button></a>}
</div>
</div>
</div>
}
}
//執行actionCreator函式才表示派發指令
export default connect((state)=>{
return {...state.course}
},actions.course)(Course);