欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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)目開發(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文件中添加全局Spinmain.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)打開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)聽到,

說(shuō)到監(jiān)聽是不是就想到了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)聽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)聽來(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)文章

  • 詳解關(guān)于React-Router4.0跳轉(zhuǎn)不置頂解決方案

    詳解關(guān)于React-Router4.0跳轉(zhuǎn)不置頂解決方案

    這篇文章主要介紹了詳解關(guān)于React-Router4.0跳轉(zhuǎn)不置頂解決案,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-05-05
  • React使用useEffect解決setState副作用詳解

    React使用useEffect解決setState副作用詳解

    這篇文章主要為大家介紹了React使用useEffect解決setState副作用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • react路由守衛(wèi)的實(shí)現(xiàn)(路由攔截)

    react路由守衛(wèi)的實(shí)現(xiàn)(路由攔截)

    react不同于vue,通過(guò)在路由里設(shè)置meta元字符實(shí)現(xiàn)路由攔截。本文就詳細(xì)的介紹一下,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • React如何實(shí)現(xiàn)瀏覽器打印部分內(nèi)容詳析

    React如何實(shí)現(xiàn)瀏覽器打印部分內(nèi)容詳析

    這篇文章主要給大家介紹了關(guān)于利用React如何實(shí)現(xiàn)瀏覽器打印部分內(nèi)容的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用React具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • react為什么不推薦使用index作為key

    react為什么不推薦使用index作為key

    本文主要介紹了react為什么不推薦使用index作為key,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • React中useEffect Hook常見問(wèn)題及解決

    React中useEffect Hook常見問(wèn)題及解決

    React的useEffect Hook它允許我們?cè)诤瘮?shù)組件中執(zhí)行副作用操作,但在使用過(guò)程中可能會(huì)遇到一些常見的錯(cuò)誤,本文就來(lái)介紹一下常見問(wèn)題及解決,感興趣的可以了解一下
    2023-10-10
  • 基于React封裝一個(gè)驗(yàn)證碼輸入控件

    基于React封裝一個(gè)驗(yàn)證碼輸入控件

    郵箱、手機(jī)驗(yàn)證碼輸入是許多在線服務(wù)和網(wǎng)站常見的安全驗(yàn)證方式之一,本文主要來(lái)和大家討論一下如何使用React封裝一個(gè)驗(yàn)證碼輸入控件,感興趣的可以了解下
    2024-03-03
  • React之echarts-for-react源碼解讀

    React之echarts-for-react源碼解讀

    這篇文章主要介紹了React之echarts-for-react源碼解讀,echarts-for-react的源碼非常精簡(jiǎn),本文將針對(duì)主要邏輯分析介紹,需要的朋友可以參考下
    2022-10-10
  • 使用React Native創(chuàng)建以太坊錢包實(shí)現(xiàn)轉(zhuǎn)賬等功能

    使用React Native創(chuàng)建以太坊錢包實(shí)現(xiàn)轉(zhuǎn)賬等功能

    這篇文章主要介紹了使用React Native創(chuàng)建以太坊錢包,實(shí)現(xiàn)轉(zhuǎn)賬等功能,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-07-07
  • react native實(shí)現(xiàn)往服務(wù)器上傳網(wǎng)絡(luò)圖片的實(shí)例

    react native實(shí)現(xiàn)往服務(wù)器上傳網(wǎng)絡(luò)圖片的實(shí)例

    下面小編就為大家?guī)?lái)一篇react native實(shí)現(xiàn)往服務(wù)器上傳網(wǎng)絡(luò)圖片的實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-08-08

最新評(píng)論