React复习(7):服务器相关(项目后篇)


前言

本项目主要观察浏览器向后台发出请求后的三种结果的状态,使用react-redux编写项目,react渲染视图部分,redux存储Success请求成功、Fail请求失败、Loading加载中等三种状态以及相关逻辑行为。

一、项目框架

基本流程图:
在这里插入图片描述
(流程图照片像素太低,很久以前画的了,没有备份具体以下面叙述为主)
因为前面学过了模块化编程
React复习(5):模块化项目-待办事项表
对于一个项目,模块化编程可以快速定位到要改变的文件,所以本项目也采用模块化编程。设置list功能区,具体框架如下:
在这里插入图片描述
与(5)项目代办事项一样的思路,reducer中编写三种状态对应的逻辑,action中编写三种状态下触发的函数,action会作为参数传递到reducer中,最后都导入到index中对外暴露。

二、List功能区

1.action.js
因为要和服务器进行交互,所以我们要考虑在什么时候发起axios请求,因为reducer中会存储我们定义的逻辑及状态,所以我们这里我们需要获得后台传来的数据,所以我们在编写action时进行axios请求,将请求来的数据进行分情况处理(上篇博客最后请求成功后我们得到结果数据由data.data表示 博客地址:React复习(6):服务器相关(项目前篇))。
请求的结果三种:请求成功、失败、加载中。分别定义三种处理函数,分别调用,然后返回,最后暴露export。代码如下:

// 三个构造函数
import axios from 'axios'
import {Loading,Success,Fail} from './actionType'
//发起请求函数
const axiosData=function(){
    axiosLoading()
    axios.get("/s").then((data)=>{
        var res=data.data
        axiosSuccess(res)
    }).catch(()=>{
        axiosFail()
    })
}
// 请求成功
const axiosSuccess=function(data){
    return {
        type:Success,
        data:{
            status:Success,
            list:[
                 data
            ]
        }
    }
}
// 请求失败
const axiosFail=function() {
    return {
        type:Fail,
        data:{
            status:Fail,
            list:[]
        }
    }
}
// 加载中
const axiosLoading=function(){
    return {
        type:Loading,
        data:{
            status:Loading,
            list:[]
        }
    }
}
export default axiosData

2.reducer.js
这里我们定义reducer函数,它是我们更改状态的逻辑,传入的参数是我们上一步编写的action,action返回的是经过处理后的数据:如果请求成功就将data.data发送过来,否则返回对应状态和[]。
(这里我们的data数据分两个部分status状态和list数据,reducer初始化时我们表示过)
对于action的数据,我们取里面的data覆盖原有状态state,代码如下:

//三种状态判断:请求成功、请求失败、加载中
import {Loading,Success,Fail} from './actionType'
const reducer=function(state={
    list:[],
    status:""
},action) {
    switch(action.type){
        case Loading:{
             return {
                 ...state,
                 ...action.data
             }
        }
        case Success:{
            return {
                ...state,
                ...action.data
            }
        }
        case Fail:{
            return {
                ...state,
                ...action.data
            }
        }
        default:{
            return state
        }
    }
}
export default reducer

3.index.js
对外接口文件
代码如下;

import List from './views/List'
import reducer from './reducer'
export {List,reducer}

4.List组件
简单组件框架,使用connect对外导出

import React,{Component} from 'react'
import {connect} from 'react-redux'

class List extends Component{
    constructor(props){
        super(props)
    }
    render(){
        return (
            <div>List</div>
        )
    }
}

export default connect()(List)

5.actionType
为了方便处理而提取出的变量

const Loading="Loading"
const Fail="Fail"
const Success="Success"

export {Loading,Success,Fail}

三、store创建及中间件使用

中间件了解不深,但是固定模式使用,有待学习,具体代码如下:

import {reducer} from './list/index'
import {createStore,compose,applyMiddleware} from 'redux'
import thunk from 'redux-thunk'

const middleware=[thunk];//填放中间件的位置

const storeEhances=compose(
    applyMiddleware(...middleware),
    (window && window.devToolsExtension)?window.devToolsExtension():(f)=>f
)

const store =createStore(reducer,{},storeEhances)

export default store

因为我们使用了thunk中间件,而这个中间件要求我们的action返回的是一个函数,传递的参数为dispatch,所以action代码如下:

// 三个构造函数
import axios from 'axios'
import {Loading,Success,Fail} from './actionType'
//发起请求函数
const axiosData=function(){
    return function (dispatch) {
        dispatch(axiosLoading())
        axios.get("/s").then((data)=>{
        var res=data.data
            dispatch(axiosSuccess(res))
        }).catch(()=>{
            dispatch(axiosFail())
        })
    }
}
// 请求成功
const axiosSuccess=function(data){
    return {
        type:Success,
        data:{
            status:Success,
            list:[
                 data
            ]
        }
    }
}
// 请求失败
const axiosFail=function() {
    return {
        type:Fail,
        data:{
            status:Fail,
            list:[]
        }
    }
}
// 加载中
const axiosLoading=function(){
    return {
        type:Loading,
        data:{
            status:Loading,
            list:[]
        }
    }
}
export default axiosData

四、数据的渲染

React复习(6):服务器相关(项目前篇)中我们是在react视图中直接发起的axios请求,这里我们发起请求的地方是在action文件下的axiosData函数里,所以我们通过定义mapDispatchToProps函数传入connect的方式导入axiosData方法,然后在react组件的componentDidMount生命周期方法下调用。
上一步是在向服务器请求数据,我们知道connect方法是帮助我们获取我们当前组件想要获得的状态和方法,我们需要请求数据,更改同步到状态中并渲染到视图中,所以我们不仅需要定义mapDispatchToProps,还要定义mapSateToProps去渲染我们的视图
不想说话,因为忘了改了服务器后要重新node一遍,孩子找了好久的bug,骂骂咧咧反复deBug

控制台结果:
在这里插入图片描述
先是Loading,后面便是Success和我们的数据
组件代码如下:

import React,{Component} from 'react'
import {connect} from 'react-redux'
import {axiosData} from '../action'

class List extends Component{
    constructor(props){
        super(props)
    }
   
    render(){
        const {status,list} =this.props
        console.log(this.props)
        return (
            <div>
                <p>{status}</p>
                <ul>
                {list.map((item,index)=>{
                    return <li key={index}>Name:{item.name}</li>
                })}
                </ul>
                
            </div>
        )
    }
    componentDidMount(){
        this.props.getData()
    }
}

const mapStateToProps=function(state){
    console.log(state)
    return {
         status:state.status,
         list:state.list
    }
}

const mapDispatchToProps=function(dispatch){
    return{
        getData(){
            dispatch(axiosData())
        }
    }
}

export default connect(mapStateToProps,mapDispatchToProps)(List)

最终渲染效果如下:
在这里插入图片描述
对比我们服务器传来的数据:

const express =require('express')

const app=express();
app.get('/s',(req,res)=>{
    var arr=[{
        name:"小明",
    },{
        name:"123"
    }]
    res.send(arr)
})

app.listen(4000)

五、console.log(“Fnial”)

需要注意:
1、服务器改了要重新运行
2、proxy代理服务器这里就很神奇,一句话的事情,可以实现3000端口的项目请求4000端口的数据
3、敲代码要带脑子
项目文件(文件使用要记得npm install下载相关依赖包):

链接:https://pan.baidu.com/s/1sEgSynaJWyrEhppam-rWSg 
提取码:fbrw
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值