fetch----进行数据的异步请求(2018/12/18)

基本用法
         默认是用get请求数据   如果需要向后端发送数据则直接在地址后面做拼接
            fetch(url)   //第一个参数是请求的路径
         .then((res)=>res.json())   //第一个.then返回的是一个未处理的结果集,里面包含了你想要的信息还有其他的没有经过处理的信息,最终的结果需要再次进行转义,从下一个.then中拿出来,和axios的区别就在这,axios不返回未处理的结果集
         .then((data)=>{console.log(data)})   //第二个.then是拿到我们需要的数据
       
        用post请求数据
     
   let obj = {
            username:"123",
            password:"456"
        }
 
        fetch(url,{   // fetch的第一个参数是请求路径,第二个参数是一个对象形式的配置项,里面规定了 使用post方式进行请求,并且将拿到的json数据转化成了字符串的形式中,还设置了json的请求头
            method:"post",
            body:JSON.stringify(obj),
            headers:{
                //必须要写
                "Context-type":"application/json;"
            }
        })
        .then((res)=>res.json())  //返回一个未处理的结果集
        .then((data)=>console.log(data))
 
     携带cookie进行提交
       
        {
            credentials: 'include'
        }
 
 
 
中间件(请求与回复之间的应用)
            //当我们进行数据请求的时候就要用到异步的action   保证当action发生的时候数据也能被请求到
 
安装 一个异步的中间件:cnpm i redux-promise-middleware  --dev  
 
applyMiddleware  //使用中间件
 
redux-promise-middleware  //这是中间件,可以使用异步的action  这个中间件是在action和reducer之间的应用
 
总结中间件的使用方法:
        在store中引入中间件,然后应用这个中间件,在actionCreator中写一个用于请求数据的函数,然后在payload中用fatch进行数据的请求,resolve 接收数据成功后它的值其实是给了payload,在组件中引入这个action 然后写一个函数来用dispatch接收这个action,然后用componentDidMount执行这个异步action获取数据,然后在reducer中进行数据的操作,获取到想要的数据,最终将它渲染到页面上,但是在fetch请求数据之前需要做跨域处理
src/index.js
import {createStore,combineReducers,applyMiddleware} from "redux"  //combineReducers 合并多个reducer
import reduxPromiseMiddleware from "redux-promise-middleware"  //引入中间件,使action可以被异步的请求到,这个中间件在action和reducer中间使用
import tab from "./reducer/tab";
import todoList from "./reducer/todolist"
 
const reducer =combineReducers({   
    tab,
    todoList
})
 
const store = createStore(reducer,applyMiddleware(reduxPromiseMiddleware())//使用中间件
export default store
 
action/actionCreator.js
 
import {fetch} from "whatwg-fetch"
import fetchJsonp from "fetch-jsonp"  //如果要拿到通过jsonP跨域的数据需要下载一个包 cnpm i fetch-jsonp --save
export const change_action = (val) =>({
    type:"INPUT_CHANGE",
    value:val
})
 
export const add_action = () =>({  //标红的地方是一个action方法,他返回了一个action对象,里面有action的名字和获取到的数据
    type:"ADD_ITEM"
})
 
export const del_item =(val)=>({
    type:"DEL_ITEM",
    value:val //这里的val代表的是下标
})
 
export const getdata_action=()=>({  //写一个函数用于请求数据
    
        type:"GET_DATA",
        payload:new Promise(resolve=>{  //用于数据的异步请求
            
            /*let url ="/search?frame=1&page=1&cKey=wap-index&tag=&maxPrice=&minPrice=&fcid=&_mgjuuid=701dd624-b6ee-4a04-8557-8d9bc5906b45&_=1545135280415"
            fetch(url)  //这种方法只能拿到通过正常方法返回的数据,不能拿到通过jsonp跨域返回的数据
            .then(res=>res.json())
            .then((data)=>{
                console.log(data)
                resolve(data)  //resolve 接收数据成功后它的值其实是给了payload
            })*/
 
 
 
            fetchJsonp('/search?frame=1&page=1&cKey=wap-index&tag=&maxPrice=&minPrice=&fcid=&_mgjuuid=701dd624-b6ee-4a04-8557-8d9bc5906b45&_=1545135280415')
            .then(function(response) {   //fetchJsonp可以拿到通过jsonp跨域的数据
                resolve(response.json()) //response.json()返回的就是一个已经被处理好的json数据
                console.log(response.json())
            }).catch(function(ex) {  
            console.log('parsing failed', ex)
            })
 
        })
    
})
 
component/home/home.js
 
import React,{Component} from 'react'
import Input from "./children/input"
import List from "./children/list"
import {connect} from "react-redux" //connect进行连接 在子组件中引入connect
import {change_action,add_action,del_item,getdata_action} from "../../action/actionCreator"  //将需要用到的action方法引入进来 
class Home extends Component{
    
    render(){
        let {inputVal,todoList,goodList} = this.props
        return(
            <div>
                <Input val = {inputVal}  
                handleChange={this.props.handleChange.bind(this)}
                handleAdd={this.props.handleAdd.bind(this)}/>
                <List list={todoList} handleDel = {this.props.handleDel}/>  //这是从todoList中传过来的内容
            
                <ul>
                    { //这是将从外部获取到的数据渲染到页面上
                            goodList.map((item,index)=>{
                                return <li key={index}>{item.title}</li>
                            })
 
                    }
                </ul>
            </div>
            )
    }
    componentDidMount(){ //执行异步action ,获取数据
        this.props.getData()
    }
 
}
const mapStateToProps=(state)=>({
    inputVal:state.todoList.inputVal,
    todoList:state.todoList.todoList,
    goodList:state.todoList.goodList
})
 
const mapDispatchToProps = (dispatch)=>({
    handleChange(e){
        let val = e.target.value
        dispatch(change_action(val))
    },
    handleAdd(){
        dispatch(add_action())
    },
    handleDel(index){
        dispatch(del_item(index))
    },
    getData(){
        dispatch(getdata_action())
 
    }
})
 
export default connect(mapStateToProps,mapDispatchToProps)(Home)
 
src/store/reducer/todoList.js
 
const defaultState = {
    inputVal:"",
    todoList:[],
    goodList:[]
}
 
export default (state=defaultState,action)=>{
    switch(action.type){
        case "INPUT_CHANGE":  
        let changeState = JSON.parse(JSON.stringify(state))
        changeState.inputVal=action.value  //这是input框中显示的内容
        return changeState;
        case "ADD_ITEM":
        let addState = JSON.parse(JSON.stringify(state))
        addState.todoList.push(addState.inputVal) //这是列表中显示的内容
        addState.inputVal =""  //当值被添加到列表之后就清空input框
        return addState;
        case "DEL_ITEM":
        let delState = JSON.parse(JSON.stringify(state))
        delState.todoList.splice(action.value,1)
        return delState;
        case "GET_DATA_FULFILLED" :
        //console.log(state)
        let goodState = JSON.parse(JSON.stringify(state))
        //console.log(action.payload.data.list)
        goodState.goodList    = action.payload.data.list
        return goodState
    }
    return state
}
 
跨域处理   
①在src文件夹中新建一个 setupProxy 文件夹  在里面进行跨域处理
②安装  cnpm  i http-proxy-middleware  --dev
src/setupProxy.js
const proxy = require("http-proxy-middleware")
//http://list.meilishuo.com/search?frame=1&page=1&cKey=wap-index&tag=&maxPrice=&minPrice=&fcid=&_mgjuuid=701dd624-b6ee-4a04-8557-8d9bc5906b45&_=1545135280415&callback=jsonp2
 
module.exports = (app)=>{  //设置跨域
    app.use("/search",proxy({
        target:"http://list.meilishuo.com",
        changeOrigin:true
    }))
}
 
这是用jsonp跨域返回数据的时候使用的fetch方法
import fetchJsonp from "fetch-jsonp"  //如果要拿到通过jsonP跨域的数据需要下载一个包 cnpm i fetch-jsonp --save
fetchJsonp('https://api.mogujie.com/h5/mwp.darwin.get/3/?mw-group=scene_social&mw-appkey=100028&mw-t=1545122449543&mw-uuid=bdb8ae45-897f-446c-b931-9993b50cf26b&mw-ttid=NMMain%40mgj_h5_1.0&mw-sign=a881b7af768c017c111000ca41974ef3&data=%7B%22page%22%3A1%2C%22pageSize%22%3A%2210%22%2C%22pid%22%3A126262%2C%22appPlat%22%3A%22m%22%7D')
                          .then(function(response) {
                                    resolve(response.json())
                          }).catch(function(ex) {
                          console.log('parsing failed', ex)
                          })
原文地址:https://www.cnblogs.com/zsrTaki/p/11510856.html