最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

react+ant.d添加全局loading方式

 更新時(shí)間:2024年01月24日 15:20:54   作者:土豆Coder  
這篇文章主要介紹了react+ant.d添加全局loading方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

背景

先上個(gè)應(yīng)景圖,哈哈哈!

本篇博客中的方法也是前兩天剛接觸redux時(shí)給了我的一點(diǎn)啟發(fā),可以從這里著手來(lái)實(shí)現(xiàn)這個(gè)功能。而且,事實(shí)證明,確實(shí)滿足了我的需求。

項(xiàng)目開(kāi)發(fā)中往往需要在接口返回較慢的時(shí)候給出loading狀態(tài),防止在接口返回值的過(guò)程中用戶多次點(diǎn)擊,之前我們?cè)?code>Vue中也添加過(guò)這個(gè)功能,而且還在其中遇到過(guò)由于單例模式出現(xiàn)的問(wèn)題,以及如何解決這個(gè)問(wèn)題大家可以自行百度。

Vue中全局loading組件直接通過(guò)創(chuàng)建實(shí)例的方式,在ant.d中我們的Spin組件需要包裹想要遮罩的元素,我們?nèi)绾卧谡?qǐng)求接口的入口統(tǒng)一添加全局loading呢?

這里我們就用到了reduxreact+redux超簡(jiǎn)單入門實(shí)例這里可以帶你迅速了解并使用redux

使用redux實(shí)現(xiàn)全局Loading

添加Spin

首先在main文件中添加全局Spin,main.js文件包裹了所有菜單欄所包含的內(nèi)容(除了登錄頁(yè),基本都包含在這里)

// main.js
import React, { Component } from 'react'
import AppMenu from '../../components/app-menu'
import AppBreadCrum from '../../components/app-breadcrum'
import { Switch, Route } from 'react-router-dom'
import { mainRoutes } from '../../router'
import { Spin } from 'antd'
import store from '../../store'

class Main extends Component {
	state = {
	    loading: false
	}
  render () {
    const { layout, ...rest } = this.props
    let { loading } = this.state
    return (
      <Spin spinning={loading} wrapperClassName="page-loading">
        <div className="main">
          <AppMenu {...rest}></AppMenu>
          <div className="app-right">
            <AppBreadCrum {...rest}></AppBreadCrum>
            <div className="app-bottom">
              <Switch>
                {mainRoutes.map(route => (<Route exact key={route.path} path={route.path} component={route.component}></Route>))}
              </Switch>
            </div>
          </div>
        </div>
      </Spin>
    )
  }
}

export default Main

接口攔截設(shè)置Loading顯示

我們需要在接口發(fā)出請(qǐng)求的時(shí)候設(shè)置Loading顯示,在返回以后設(shè)置其為隱藏。

actions

定義兩個(gè)action動(dòng)作,一個(gè)用來(lái)打開(kāi)loading一個(gè)用來(lái)關(guān)閉loading

// actions/index.js
export const OPENPAGELOADING = 'OpenPageLoading'
export const CLOSEPAGELOADING = 'ClosePageLoading'

reducers

通過(guò)不同事件來(lái)觸發(fā)值的改變

// reducers/index.js
import { OPENPAGELOADING, CLOSEPAGELOADING } from '../actions'
const initState = {
  pageLoadingVal: false
}
const AppReducer = (state=initState, action) => {
  switch (action.type) {
    case OpenPageLoading: {
      return {
        pageLoadingVal: true
      }
    }
    case ClosePageLoading: {
      return {
        pageLoadingVal: false
      }
    }
    default: {
      return state
    }
  }
}

export default AppReducer

store

// store/index.js
import { createStore } from 'redux'
import AppReducer from '../reducers'

const store = createStore(AppReducer)

export default store

引入

// index.js
...
import store from './store'

ReactDOM.render(
  <Provider store={store}>
    <ConfigProvider locale={antdZhCn}>
      <Router>
        <App />
      </Router>
    </ConfigProvider>
  </Provider>,
  document.getElementById('root')
)

http.js

接口入口文件中設(shè)置全局的值

import axios from 'axios'
import { message } from 'antd'
import store from '../store'
import { OPENPAGELOADING, CLOSEPAGELOADING } from '../actions'

let instance = axios.create({
  baseURL: '',
  timeout: 5000
})

/* 請(qǐng)求攔截 */
instance.interceptors.request.use(config => {
  store.dispatch({type: OPENPAGELOADING})
  return config
}, error => {
  store.dispatch({type: CLOSEPAGELOADING })
  message.error('請(qǐng)求超時(shí)')
  return Promise.reject(error)
})

/* 響應(yīng)攔截 */
instance.interceptors.response.use(response => {
  store.dispatch({type: CLOSEPAGELOADING })
  let { data } = response
  if (data && data.code && data.code === 200) {
    return data
  } else if (data && data.code && data.code === 500) {
    message.error(data.msg || '獲取接口數(shù)據(jù)錯(cuò)誤')
    return Promise.reject()
  }
}, error => {
  store.dispatch({type: CLOSEPAGELOADING })
  message.error('服務(wù)錯(cuò)誤')
  return Promise.reject(error)
})

export default instance

在發(fā)出接口請(qǐng)求的時(shí)候通過(guò)store.dispatch({type: 'OpenPageLoading'})派發(fā)操作

需要注意的時(shí)候,在無(wú)論接口返回是什么的情況下需要通過(guò)store.dispatch({type: 'ClosePageLoading'})來(lái)關(guān)閉loading

監(jiān)測(cè)store中l(wèi)oading值設(shè)置是否顯示Spin

到此為止我們store中的全局loading的值已經(jīng)發(fā)生了滿足需求的改變,

下面要做的就是在每次值發(fā)生改變的時(shí)候我們能在使用Spin的地方監(jiān)聽(tīng)到,

說(shuō)到監(jiān)聽(tīng)是不是就想到了store提供的subscribe方法呢?怎么做呢?

// main.js
import React, { Component } from 'react'
import AppMenu from '../../components/app-menu'
import AppBreadCrum from '../../components/app-breadcrum'
import { Switch, Route } from 'react-router-dom'
import { mainRoutes } from '../../router'
import { Spin } from 'antd'
import store from '../../store'

class Main extends Component {
	state = {
    	loading: false
	}
  componentDidMount () {
  	// 重點(diǎn)
  	// 重點(diǎn)
  	// 重點(diǎn)
  	// 監(jiān)聽(tīng)store中pageLoadingVal值
    store.subscribe(() => {
      let storeState = store.getState()
      this.setState({
        loading: storeState.pageLoadingVal
      })
    })
  }
  render () {
    const { layout, ...rest } = this.props
    let { loading } = this.state
    return (
      <Spin spinning={loading} wrapperClassName="page-loading">
        // ...
      </Spin>
    )
  }
}

export default Main

是的,通過(guò)監(jiān)聽(tīng)來(lái)設(shè)置當(dāng)前組件的state的值。

優(yōu)化

如果你一個(gè)頁(yè)面只有一個(gè)接口,那么你完成上述就搞定了。

但是,如果你一個(gè)頁(yè)面有多個(gè)接口,當(dāng)其中有個(gè)接口返回值很慢的時(shí)候你就會(huì)發(fā)現(xiàn)問(wèn)題,就是當(dāng)一個(gè)接口pending結(jié)束全局loading就消失了,這個(gè)當(dāng)然不是我們想要的結(jié)果,理想的亞子是當(dāng)前頁(yè)面所有接口都pending結(jié)束后才消失loading

這個(gè)問(wèn)題之前在做elementUI+Vue做全局loading時(shí)候也遇到過(guò),其實(shí)思路是一樣的,思路可參考elementUI全局Loading單例模式。

因?yàn)閯?chuàng)建全局loading的方式不同,所以這里思路一樣,代碼稍有不同

// http.js

import axios from 'axios'
import { message } from 'antd'
import store from '../store'
import { OPENPAGELOADING, CLOSEPAGELOADING } from '../actions'

let instance = axios.create({
  baseURL: '',
  timeout: 5000
})

/* 添加一個(gè)計(jì)數(shù)器 */
let needLoadingRequestCount = 0

function showFullScreenLoading () {
  if (needLoadingRequestCount === 0) {
    store.dispatch({type: OPENPAGELOADING})
  }
  needLoadingRequestCount++
}

function tryHideFullScreenLoading () {
  if (needLoadingRequestCount <= 0) return
  needLoadingRequestCount--
  if (needLoadingRequestCount === 0) {
    store.dispatch({type: CLOSEPAGELOADING})
  }
}

/* 請(qǐng)求攔截 */
instance.interceptors.request.use(config => {
  showFullScreenLoading()
  return config
}, error => {
  tryHideFullScreenLoading()
  message.error('請(qǐng)求超時(shí)')
  return Promise.reject(error)
})

/* 響應(yīng)攔截 */
instance.interceptors.response.use(response => {
  tryHideFullScreenLoading()
  let { data } = response
  if (data && data.code && data.code === 200) {
    return data
  } else if (data && data.code && data.code === 500) {
    message.error(data.msg || '獲取接口數(shù)據(jù)錯(cuò)誤')
    return Promise.reject()
  }
}, error => {
  tryHideFullScreenLoading()
  message.error('服務(wù)錯(cuò)誤')
  return Promise.reject(error)
})

export default instance

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • React Native自定義組件與輸出方法詳解

    React Native自定義組件與輸出方法詳解

    這篇文章主要給大家介紹了關(guān)于React Native自定義組件與輸出方法的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-07-07
  • React Native 啟動(dòng)流程詳細(xì)解析

    React Native 啟動(dòng)流程詳細(xì)解析

    這篇文章主要介紹了React Native 啟動(dòng)流程簡(jiǎn)析,文以 react-native-cli 創(chuàng)建的示例工程(安卓部分)為例,給大家分析 React Native 的啟動(dòng)流程,需要的朋友可以參考下
    2021-08-08
  • React實(shí)現(xiàn)antdM的級(jí)聯(lián)菜單實(shí)例

    React實(shí)現(xiàn)antdM的級(jí)聯(lián)菜單實(shí)例

    這篇文章主要為大家介紹了React實(shí)現(xiàn)antdM的級(jí)聯(lián)菜單實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • react MPA 多頁(yè)配置詳解

    react MPA 多頁(yè)配置詳解

    這篇文章主要介紹了react MPA 多頁(yè)配置詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • React使用UI(Ant?Design)框架的詳細(xì)過(guò)程

    React使用UI(Ant?Design)框架的詳細(xì)過(guò)程

    Ant?Design主要用于中后臺(tái)系統(tǒng)的使用,它提供了豐富的組件和工具,可以幫助開(kāi)發(fā)人員快速構(gòu)建出美觀、易用的界面,同時(shí),Ant?Design還提供了詳細(xì)的文檔和示例,方便開(kāi)發(fā)者學(xué)習(xí)和使用,這篇文章主要介紹了React使用UI(Ant?Design)框架,需要的朋友可以參考下
    2023-12-12
  • React Fiber樹(shù)的構(gòu)建和替換過(guò)程講解

    React Fiber樹(shù)的構(gòu)建和替換過(guò)程講解

    React Fiber樹(shù)的創(chuàng)建和替換過(guò)程運(yùn)用了雙緩存技術(shù),直接將舊的 fiber 樹(shù)替換成新的 fiber 樹(shù),這樣做的好處是省去了直接在頁(yè)面上渲染時(shí)的計(jì)算時(shí)間,避免計(jì)算量大導(dǎo)致的白屏、卡頓,現(xiàn)在你一定還不太理解,下面進(jìn)行詳細(xì)講解,需要的朋友可以參考下
    2022-12-12
  • Remix?路由模塊輸出對(duì)象handle函數(shù)

    Remix?路由模塊輸出對(duì)象handle函數(shù)

    這篇文章主要為大家介紹了Remix?路由模塊輸出對(duì)象handle函數(shù)使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • React常見(jiàn)的?HOC?使用案例及示例代碼

    React常見(jiàn)的?HOC?使用案例及示例代碼

    高階組件(Higher-Order?Component,HOC)是一種用于在?React?中復(fù)用組件邏輯的技術(shù),這篇文章主要介紹了React常見(jiàn)的?HOC?使用案例示例代碼,需要的朋友可以參考下
    2024-08-08
  • react使用antd-design中select不能及時(shí)刷新問(wèn)題及解決

    react使用antd-design中select不能及時(shí)刷新問(wèn)題及解決

    這篇文章主要介紹了react使用antd-design中select不能及時(shí)刷新問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • concent漸進(jìn)式重構(gòu)react應(yīng)用使用詳解

    concent漸進(jìn)式重構(gòu)react應(yīng)用使用詳解

    這篇文章主要為大家介紹了concent漸進(jìn)式重構(gòu)react應(yīng)用的使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11

最新評(píng)論

渝北区| 共和县| 修水县| 德钦县| 石柱| 仁化县| 遵义县| 淮阳县| 肥城市| 建瓯市| 甘德县| 福建省| 珠海市| 房山区| 鹤峰县| 桐庐县| 定日县| 凭祥市| 建宁县| 兴义市| 乌苏市| 清远市| 屏南县| 长宁县| 隆尧县| 双峰县| 阿巴嘎旗| 柳江县| 六枝特区| 博客| 平顺县| 周至县| 灌南县| 星子县| 甘孜县| 灵山县| 盐亭县| 牟定县| 江孜县| 凭祥市| 博爱县|