成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

面試官:說說對高階組件的理解?應用場景?

開發 前端
在React中,高階組件即接受一個或多個組件作為參數并且返回一個組件,本質也就是一個函數,并不是一個組件。

[[410684]]

本文轉載自微信公眾號「JS每日一題」,作者灰灰。轉載本文請聯系JS每日一題公眾號。

一、是什么

高階函數(Higher-order function),至少滿足下列一個條件的函數

  1. 接受一個或多個函數作為輸入
  2. 輸出一個函數

在React中,高階組件即接受一個或多個組件作為參數并且返回一個組件,本質也就是一個函數,并不是一個組件

  1. const EnhancedComponent = highOrderComponent(WrappedComponent); 

上述代碼中,該函數接受一個組件WrappedComponent作為參數,返回加工過的新組件EnhancedComponent

高階組件的這種實現方式,本質上是一個裝飾者設計模式

二、如何編寫

最基本的高階組件的編寫模板如下:

  1. import React, { Component } from 'react'
  2.  
  3. export default (WrappedComponent) => { 
  4.   return class EnhancedComponent extends Component { 
  5.     // do something 
  6.     render() { 
  7.       return <WrappedComponent />; 
  8.     } 
  9.   } 

通過對傳入的原始組件 WrappedComponent 做一些你想要的操作(比如操作 props,提取 state,給原始組件包裹其他元素等),從而加工出想要的組件 EnhancedComponent

把通用的邏輯放在高階組件中,對組件實現一致的處理,從而實現代碼的復用

所以,高階組件的主要功能是封裝并分離組件的通用邏輯,讓通用邏輯在組件間更好地被復用

但在使用高階組件的同時,一般遵循一些約定,如下:

  • props 保持一致
  • 你不能在函數式(無狀態)組件上使用 ref 屬性,因為它沒有實例
  • 不要以任何方式改變原始組件 WrappedComponent
  • 透傳不相關 props 屬性給被包裹的組件 WrappedComponent
  • 不要再 render() 方法中使用高階組件
  • 使用 compose 組合高階組件
  • 包裝顯示名字以便于調試

這里需要注意的是,高階組件可以傳遞所有的props,但是不能傳遞ref

如果向一個高階組件添加refe引用,那么ref 指向的是最外層容器組件實例的,而不是被包裹的組件,如果需要傳遞refs的話,則使用React.forwardRef,如下:

  1. function withLogging(WrappedComponent) { 
  2.     class Enhance extends WrappedComponent { 
  3.         componentWillReceiveProps() { 
  4.             console.log('Current props', this.props); 
  5.             console.log('Next props', nextProps); 
  6.         } 
  7.         render() { 
  8.             const {forwardedRef, ...rest} = this.props; 
  9.             // 把 forwardedRef 賦值給 ref 
  10.             return <WrappedComponent {...rest} ref={forwardedRef} />; 
  11.         } 
  12.     }; 
  13.  
  14.     // React.forwardRef 方法會傳入 props 和 ref 兩個參數給其回調函數 
  15.     // 所以這邊的 ref 是由 React.forwardRef 提供的 
  16.     function forwardRef(props, ref) { 
  17.         return <Enhance {...props} forwardRef={ref} /> 
  18.     } 
  19.  
  20.     return React.forwardRef(forwardRef); 
  21. const EnhancedComponent = withLogging(SomeComponent); 

三、應用場景

通過上面的了解,高階組件能夠提高代碼的復用性和靈活性,在實際應用中,常常用于與核心業務無關但又在多個模塊使用的功能,如權限控制、日志記錄、數據校驗、異常處理、統計上報等

舉個例子,存在一個組件,需要從緩存中獲取數據,然后渲染。一般情況,我們會如下編寫:

  1. import React, { Component } from 'react' 
  2.  
  3. class MyComponent extends Component { 
  4.  
  5.   componentWillMount() { 
  6.       let data = localStorage.getItem('data'); 
  7.       this.setState({data}); 
  8.   } 
  9.    
  10.   render() { 
  11.     return <div>{this.state.data}</div> 
  12.   } 

上述代碼當然可以實現該功能,但是如果還有其他組件也有類似功能的時候,每個組件都需要重復寫componentWillMount中的代碼,這明顯是冗雜的

下面就可以通過高價組件來進行改寫,如下:

  1. import React, { Component } from 'react' 
  2.  
  3. function withPersistentData(WrappedComponent) { 
  4.   return class extends Component { 
  5.     componentWillMount() { 
  6.       let data = localStorage.getItem('data'); 
  7.         this.setState({data}); 
  8.     } 
  9.      
  10.     render() { 
  11.       // 通過{...this.props} 把傳遞給當前組件的屬性繼續傳遞給被包裝的組件WrappedComponent 
  12.       return <WrappedComponent data={this.state.data} {...this.props} /> 
  13.     } 
  14.   } 
  15.  
  16. class MyComponent2 extends Component {   
  17.   render() { 
  18.     return <div>{this.props.data}</div> 
  19.   } 
  20.  
  21. const MyComponentWithPersistentData = withPersistentData(MyComponent2) 

再比如組件渲染性能監控,如下:

  1. class Home extends React.Component { 
  2.     render() { 
  3.         return (<h1>Hello World.</h1>); 
  4.     } 
  5. function withTiming(WrappedComponent) { 
  6.     return class extends WrappedComponent { 
  7.         constructor(props) { 
  8.             super(props); 
  9.             this.start = 0; 
  10.             this.end = 0; 
  11.         } 
  12.         componentWillMount() { 
  13.             super.componentWillMount && super.componentWillMount(); 
  14.             this.start = Date.now(); 
  15.         } 
  16.         componentDidMount() { 
  17.             super.componentDidMount && super.componentDidMount(); 
  18.             this.end = Date.now(); 
  19.             console.log(`${WrappedComponent.name} 組件渲染時間為 ${this.end - this.start} ms`); 
  20.         } 
  21.         render() { 
  22.             return super.render(); 
  23.         } 
  24.     }; 
  25.  
  26. export default withTiming(Home); 

參考文獻

https://zh-hans.reactjs.org/docs/higher-order-components.html#gatsby-focus-wrapper

https://zh.wikipedia.org/wiki/%E9%AB%98%E9%98%B6%E5%87%BD%E6%95%B0

https://segmentfault.com/a/1190000010307650

https://zhuanlan.zhihu.com/p/61711492

 

責任編輯:武曉燕 來源: JS每日一題
相關推薦

2021-05-31 10:35:34

TCPWebSocket協議

2021-07-07 08:36:45

React應用場景

2021-06-07 09:41:48

NodeBuffer 網絡協議

2021-06-08 08:33:23

NodeStream數據

2021-09-16 07:52:18

算法應用場景

2021-06-30 07:19:36

React事件機制

2021-11-05 07:47:56

代理模式對象

2021-11-09 08:51:13

模式命令面試

2021-11-10 07:47:49

組合模式場景

2021-11-04 06:58:32

策略模式面試

2021-08-16 08:33:26

git

2021-11-03 14:10:28

工廠模式場景

2021-09-06 10:51:27

TypeScriptJavaScript

2021-09-28 07:12:09

測試路徑

2021-11-11 16:37:05

模板模式方法

2021-11-22 23:50:59

責任鏈模式場景

2021-09-29 07:24:20

場景數據

2021-07-09 08:33:35

React組件受控

2021-09-10 06:50:03

TypeScript裝飾器應用

2021-10-08 09:59:32

冒泡排序場景
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 狠狠入ady亚洲精品经典电影 | 天天综合网永久 | 毛片免费在线观看 | 男人亚洲天堂 | 国产精品久久久久久久久久久久 | 国产一区二区三区久久久久久久久 | 欧美日日 | 日本精品在线一区 | 国产成人av电影 | 成人av网站在线观看 | 女朋友的闺蜜3韩国三级 | 成人av资源在线 | 亚洲视频在线免费观看 | 成年女人免费v片 | 欧美久久久电影 | 精品一区在线 | 国产91丝袜在线播放 | 久久久九九 | 天天躁日日躁狠狠躁白人 | 日韩免费一区二区 | 久久久久久久久久久久久91 | 欧美日韩国产欧美 | 免费黄篇 | 人人草天天草 | 中文字幕国产一区 | 一区二区三区亚洲 | 久久久久国产一区二区三区 | 日本成人在线播放 | 国产精品久久久久久久免费大片 | 日韩一二三区 | 成人h动漫亚洲一区二区 | 中文字幕av一区二区三区 | 亚洲欧美在线视频 | 欧美在线一区二区三区 | 亚洲国产精品一区 | 伊人免费观看视频 | 国精产品一区一区三区免费完 | 色欧美综合 | 久久精品视频一区二区 | 亚洲日韩中文字幕一区 | 国产精品久久久久久久久久久久午夜片 |