自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

俺好像看懂了公司前端代碼

開(kāi)發(fā) 前端
今天的重點(diǎn)是React或React Native如何高效管理調(diào)用后端接口,和上篇講到Vue管理后端接口一樣,它們有很多相似性,也有不同之處,因?yàn)槲覀冎浪鼈冮_(kāi)發(fā)模式和方法有些不同。

他來(lái)了,他來(lái)了,

他掉著頭發(fā)走來(lái)了。

大家好,我是前端開(kāi)發(fā)者卜壯,經(jīng)過(guò)筆者上篇《俺咋能看懂公司前端項(xiàng)目?》之后,不知道大家有沒(méi)有學(xué)到其設(shè)計(jì)思想并應(yīng)用到自己的項(xiàng)目中。我相信你們,肯定沒(méi)有。

 

[[328644]]

趁著頭發(fā)茂密,讓我們步入正題!

今天的主角React,它作為當(dāng)今社會(huì)的前端主流框架,在前端框架江湖中算是一哥的存在,憑借小巧高效靈活等特點(diǎn),完成了眾多企業(yè)級(jí)的大項(xiàng)目,并且衍生了很多其他的框架,比如像跨平臺(tái)移動(dòng)開(kāi)發(fā)React Native,它的一套代碼可以運(yùn)行在Android和iOS。然而這些都不是本篇文章的重點(diǎn)。

 

[[328645]]

今天的重點(diǎn)是React或React Native如何高效管理調(diào)用后端接口,和上篇講到Vue管理后端接口一樣,它們有很多相似性,也有不同之處,因?yàn)槲覀冎浪鼈冮_(kāi)發(fā)模式和方法有些不同。

起初的想法,Vue有自己?jiǎn)为?dú)的狀態(tài)管理器Vuex,React也可以用Redux來(lái)管理狀態(tài);Vue提供了混入(mixins)的開(kāi)發(fā)方式,雖然React起初也有混入的功能,后來(lái)被舍棄掉了,但是React可以通過(guò)高階組件來(lái)實(shí)現(xiàn)混入的功能?;谶@些想法,該出手時(shí)就出手,風(fēng)風(fēng)火火參北斗啊。

后來(lái),我終于學(xué)會(huì)了讓自己愛(ài)自己,搞錯(cuò)了,我終于學(xué)會(huì)了Redux以及React-redux,學(xué)起來(lái)其實(shí)和Vuex一樣,只是有些概念不一樣。

Vuex里面有State定義狀態(tài)、Mutation修改狀態(tài)、Action支持異步調(diào)用Mutation修改狀態(tài)、Getter從State派生狀態(tài)。

而在Redux中主要有Reducer和Action,Reducer是一個(gè)純函數(shù),根據(jù)不同的Action返回不同的狀態(tài),Action則是用于改變狀態(tài)唯一途徑。但是僅靠Redux提供的功能只支持同步修改狀態(tài),但是Redux有很多中間件,其中Redux-thunk就是一個(gè)支持異步的中間件,因?yàn)槭褂肦edux管理請(qǐng)求需要異步支持,所以,I want you。

 

[[328646]]

哆來(lái)咪發(fā)梭拉稀

又唱上了。

前面說(shuō)了那么多都是湊字?jǐn)?shù),

下面開(kāi)始我們的步驟。

首先先了解一下前端管理后臺(tái)接口的架構(gòu)設(shè)計(jì)流程,技術(shù)選型后端要使用Swagger接口管理,前端React使用Redux狀態(tài)管理,React-redux狀態(tài)映射組件Props,Redux-thunk支持異步管理狀態(tài),解析Swagger需要用到Handlebars模板編譯和fs文件解析。

 

俺好像看懂了公司前端代碼

1、引入swagger。

后臺(tái)接口服務(wù)器引入swagger。這一步就不多說(shuō)了,你有我有全都有啊,誒嘿,誒嘿,參北斗啊。

2、解析swagger生成controller。

可以通過(guò)js寫一個(gè)腳本生成指定格式的js文件。swagger提供的v2/api-docs網(wǎng)址可以訪問(wèn)接口的json。這個(gè)json是一個(gè)固定格式的字符串,包含tags數(shù)組和path對(duì)象。通過(guò)Handlebars模板編譯和fs文件解析生成以下格式的js文件,每個(gè)類對(duì)應(yīng)一個(gè)文件。同時(shí)生成一個(gè)index.js入口文件,將所有的controller文件集中裝飾處理。

  1. export default{     
  2.   actions: {         
  3.     findById : {             
  4.       summary: '按主鍵查詢',             
  5.       method: 'get',             
  6.       url: (payload) => `/api/user/${payload.id}`,             
  7.       parameters: [{'name':'id','in':'path','description':'id','required':true,'type':'string'}],        
  8.     },    
  9.   },} 

3、為每個(gè)controller文件生成對(duì)應(yīng)的actions和reducers函數(shù)。

上述所說(shuō)的入口文件index.js用來(lái)裝飾每一個(gè)controller,裝飾的內(nèi)容就是遍歷controller文件的actions對(duì)象,生成actions函數(shù)和reducers純函數(shù)。最后將生成的reducers交給redux管理,actions則為組件提供調(diào)用。actions函數(shù)里面有三步,包括請(qǐng)求前,請(qǐng)求中和請(qǐng)求后對(duì)狀態(tài)的處理。這三步是為了設(shè)置接口請(qǐng)求的loading狀態(tài),通過(guò)loading狀態(tài)來(lái)處理頁(yè)面的加載效果,省去在組件中自定義的邏輯判斷。下圖為每個(gè)接口在action函數(shù)的數(shù)據(jù)處理。

 

俺好像看懂了公司前端代碼

生成action和reducer的代碼:

  1. export default (name, controller) => {     
  2.   const defaultState = (type) => ({//設(shè)置請(qǐng)求前的數(shù)據(jù)狀態(tài),生成reducer時(shí)使用        
  3.     type: type,         
  4.     loading: false,         
  5.     error: null,         
  6.     request: null,         
  7.     data: {},     
  8.   })     
  9.   const start_request = (type) => ({//設(shè)置開(kāi)始請(qǐng)求的數(shù)據(jù)狀態(tài)        
  10.     type: type,         
  11.     loading: true,         
  12.     error: null,         
  13.     request: null,         
  14.     data: {},     
  15.   })     
  16.   let actions = {}     
  17.   let reducers = {}    //遍歷生成的controller文件的actions     
  18.   _.forEach(_.keys(controller.actions), key => {         
  19.     const action = controller.actions[key]         
  20.     //生成action         
  21.     actions[`${name}_${key}`] = (payload) => {             
  22.       return async (dispatch) => {                 
  23.         //設(shè)置開(kāi)始請(qǐng)求的數(shù)據(jù)狀態(tài)                 
  24.         dispatch(start_request(`${name}_${key}`))                 
  25.         //開(kāi)始網(wǎng)絡(luò)請(qǐng)求                
  26.         let resp = {}                 
  27.         try {                     
  28.           resp = await ajaxUtil.myRequest(action, payload)                 
  29.         } catch (e) {                     
  30.           resp = e                }                 
  31.         let handleResult = null                
  32.         //數(shù)據(jù)處理,這里對(duì)resp.status狀態(tài)碼為400-500的錯(cuò)誤處理,和200-300的成功數(shù)據(jù)處理                 
  33.         if (!resp) {                     
  34.           handleResult = {                         
  35.             type: `${name}_${key}`,                        
  36.             loading: false,                       
  37.             error: '系統(tǒng)錯(cuò)誤',                       
  38.             data: null,                     
  39.           }                
  40.         } else if (resp.status >= 400 && resp.status < 500) {                     
  41.           handleResult = {...}                 
  42.                          } else if (resp.status >= 500) {                    
  43.                            handleResult = {...}                 
  44.                                           } else if (resp.status >= 200 && resp.status < 300) {                    
  45.                                             handleResult = {                        
  46.                                               type: `${name}_${key}`,                        
  47.                                               loading: false,                        
  48.                                               error: null,                        
  49.                                               request: payload,                         
  50.                                               data: resp.data,                     
  51.                                             }                 
  52.                                           }                 
  53.                            //請(qǐng)求結(jié)束數(shù)據(jù)狀態(tài)處理                 
  54.                            dispatch(handleResult)                 
  55.                            return handleResult            
  56.                          }         
  57.         }         
  58.         //生成reducer         
  59.         reducers[`${name}_${key}`] = (state = defaultState(`${name}_${key}`), action) => {             
  60.           if (action.type === `${name}_${key}`) {                 
  61.             return {...state, ...action}             
  62.           } else {                 
  63.             return state             
  64.           }         
  65.         }     
  66.       })     
  67.       return {...actions, reducers} 
  68.     } 

4、封裝高階組件,將接口請(qǐng)求狀態(tài)數(shù)據(jù)映射到組件的props中。

vuex里面有四個(gè)輔助函數(shù)這個(gè)react-redux要登場(chǎng)了。react-redux提供了一個(gè)connect,它是一個(gè)高階組件,接收 React 組件作為輸入,輸出一個(gè)新的 React 組件。高階組件讓代碼更具有復(fù)用性、邏輯性與抽象特征??梢詫?duì) render 方法作劫持,也可以控制 props 與 state。我們這里需要自己封裝一個(gè)高階組件,里面調(diào)用react-redux提供的connect函數(shù)將state和dispatch映射到組件的props,此外還需要定義兩個(gè)函數(shù)映射到props中,一個(gè)是用于調(diào)用接口的函數(shù),另一個(gè)是獲取請(qǐng)求接口的loading狀態(tài)函數(shù)。最后返回一個(gè)新的組件。

高階組件封裝如下:

  1. export default function connect(states = null, dispatches = null) {     
  2.   return (WrappedComponent) => {         
  3.     const mapStateToProps = state => {             
  4.       //該函數(shù)用于獲取網(wǎng)絡(luò)請(qǐng)求的loading,用于組件顯示加載中的指示             
  5.       const loading = (scope) => {                 
  6.         return state[`${scope.controller}_${scope.method}`].loading             
  7.       }            
  8.       return states ? {...state, ...states(state), loading} : {...state, loading}         
  9.     }         
  10.     //集中處理請(qǐng)求發(fā)送的異常         
  11.     const error = (cbData) => {             
  12.       //判斷cbData.error,用來(lái)alert()提示用戶錯(cuò)誤信息         
  13.     }         
  14.     const mapDispatchToProps = dispatchAsync => {             
  15.       //該函數(shù)用于組件中發(fā)起網(wǎng)絡(luò)請(qǐng)求            
  16.       const dispatch = async (scope, payload) => {                
  17.         const controller = Controller[scope.controller]                 
  18.         let cbData = await dispatchAsync(controller[`${scope.controller}_${scope.method}`](payload))                 
  19.         error(cbData)                 
  20.         return cbData             
  21.       }             
  22.       return dispatches ? {...dispatches(dispatchAsync), dispatch} : {dispatch}        
  23.     }         
  24.     //reduxConnect是react-redux提供的,原名稱是connect,我這里起了個(gè)別名,為了避免和我封裝的高階組件名沖突         
  25.     //import {connect as reduxConnect} from 'react-redux'         
  26.     const Root = reduxConnect(mapStateToProps, mapDispatchToProps)(WrappedComponent)         
  27.     return class HOC extends React.Component {             
  28.       render() {                
  29.         return <Root {...this.props}/>             
  30.       }         
  31.     }    
  32.   }}​ 

5、組件引用自定義的高階組件。

如果組件涉及到網(wǎng)絡(luò)請(qǐng)求,可以引入。引入之后像這樣:

export default connect(mapStateToProps, mapDispatchToProps)(Home),其中Home是組件,mapStateToProps和mapDispatchToProps是想要指定映射哪些數(shù)據(jù)到props中,可以不傳。

然后就可以為所欲為了,發(fā)起網(wǎng)絡(luò)請(qǐng)求this.props.dispatch(IUserController.findById,{id}),返回值是請(qǐng)求后的數(shù)據(jù)。獲取請(qǐng)求狀態(tài)this.props.loading(IUserController.findById),返回值是true或false。

上文我著重說(shuō)的是react如何管理調(diào)用接口,其實(shí)react native設(shè)計(jì)是一模一樣的,大伙不妨試著設(shè)計(jì)一下。

許多事,

都是要經(jīng)過(guò)不斷嘗試才會(huì)成功的。

這篇內(nèi)容就到這里,我們下篇再見(jiàn)。

責(zé)任編輯:未麗燕 來(lái)源: 今日頭條
相關(guān)推薦

2024-08-12 12:30:27

2024-04-29 09:25:19

2021-10-28 19:35:02

代碼main方法

2023-06-27 07:09:39

2022-06-28 08:42:03

磁盤kafka高性能

2022-11-28 07:10:57

2011-09-02 16:08:09

Sencha ToucAPI文檔

2019-05-16 09:38:04

Redis高可用數(shù)據(jù)

2017-10-18 12:41:50

PC市場(chǎng)電腦潛規(guī)則

2024-09-29 08:47:55

2024-05-17 09:44:49

Kubernetes均衡器Envoy

2024-03-05 18:19:07

localhostLinux數(shù)據(jù)庫(kù)

2017-04-13 14:54:56

互聯(lián)網(wǎng)

2021-04-26 10:30:43

USB4設(shè)備Thunderbolt

2024-09-10 10:21:19

2018-01-04 00:10:52

物聯(lián)網(wǎng)技術(shù)信息

2022-03-18 00:17:30

NISTICS安全

2019-11-20 15:40:48

CPU軟件處理器

2017-01-12 14:52:51

代碼

2018-07-09 14:24:32

區(qū)塊鏈
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)