React书城小案例

步骤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);

猜你喜欢

转载自blog.csdn.net/aminwangaa/article/details/84937631