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

深入理解React高階組件

 更新時(shí)間:2017年09月28日 08:30:45   作者:QxQstar  
本篇文章主要介紹了深入理解React高階組件,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

1.在React中higher-order component (HOC)是一種重用組件邏輯的高級(jí)技術(shù)。HOC不是React API中的一部分。HOC是一個(gè)函數(shù),該函數(shù)接收一個(gè)組件并且返回一個(gè)新組件。在React中,組件是代碼復(fù)用的基本單位。

2.為了解釋HOCs,舉下面兩個(gè)例子

CommentList組件會(huì)渲染出一個(gè)comments列表,列表中的數(shù)據(jù)來自于外部。

class CommentList extends React.Component {

  constructor() {

   super();

   this.handleChange = this.handleChange.bind(this);

   this.state = {

    // "DataSource" is some global data source

    comments: DataSource.getComments()

   };

  }

 

  componentDidMount() {

   // Subscribe to changes

   DataSource.addChangeListener(this.handleChange);

  }

 

  componentWillUnmount() {

   // Clean up listener

   DataSource.removeChangeListener(this.handleChange);

  }

 

  handleChange() {

   // Update component state whenever the data source changes

   this.setState({

    comments: DataSource.getComments()

   });

  }

 

  render() {

   return (

    <div>

     {this.state.comments.map((comment) => (

      <Comment comment={comment} key={comment.id} />

     ))}

    </div>

   );

  }

 } 

 接下來是BlogPost組件,這個(gè)組件用于展示一篇博客信息

class BlogPost extends React.Component {

  constructor(props) {

   super(props);

   this.handleChange = this.handleChange.bind(this);

   this.state = {

    blogPost: DataSource.getBlogPost(props.id)

   };

  }

 

  componentDidMount() {

   DataSource.addChangeListener(this.handleChange);

  }

 

  componentWillUnmount() {

   DataSource.removeChangeListener(this.handleChange);

  }

 

  handleChange() {

   this.setState({

    blogPost: DataSource.getBlogPost(this.props.id)

   });

  }

 

  render() {

   return <TextBlock text={this.state.blogPost} />;

  }

 } 

這兩個(gè)組件是不一樣的,它們調(diào)用了DataSource的不同方法,并且它們的輸出也不一樣,但是它們中的大部分實(shí)現(xiàn)是一樣的:

1.裝載完成后,給DataSource添加了一個(gè)change listener
2.當(dāng)數(shù)據(jù)源發(fā)生變化后,在監(jiān)聽器內(nèi)部調(diào)用setState
3.卸載之后,移除change listener

可以想象在大型應(yīng)用中,相同模式的訪問DataSource和調(diào)用setState會(huì)一次又一次的發(fā)生。我們希望抽象這個(gè)過程,從而讓我們只在一個(gè)地方定義這個(gè)邏輯,然后在多個(gè)組件中共享。

接下來我們寫一個(gè)創(chuàng)建組件的函數(shù),這個(gè)函數(shù)接受兩個(gè)參數(shù),其中一個(gè)參數(shù)是組件,另一個(gè)參數(shù)是函數(shù)。下面調(diào)用withSubscription函數(shù)

const CommentListWithSubscription = withSubscription(

 CommentList,

 (DataSource) => DataSource.getComments()

);

 

const BlogPostWithSubscription = withSubscription(

 BlogPost,

 (DataSource, props) => DataSource.getBlogPost(props.id)

); 

調(diào)用withSubscription傳的第一個(gè)參數(shù)是wrapped 組件,第二個(gè)參數(shù)是一個(gè)函數(shù),該函數(shù)用于檢索數(shù)據(jù)。

當(dāng)CommentListWithSubscription和BlogPostWithSubscription被渲染,CommentList和BlogPost會(huì)接受一個(gè)叫做data的prop,data中保存了當(dāng)前從DataSource中檢索出的數(shù)據(jù)。withSubscription代碼如下:

// This function takes a component...

function withSubscription(WrappedComponent, selectData) {

 // ...and returns another component...

 return class extends React.Component {

  constructor(props) {

   super(props);

   this.handleChange = this.handleChange.bind(this);

   this.state = {

    data: selectData(DataSource, props)

   };

  }

 

  componentDidMount() {

   // ... that takes care of the subscription...

   DataSource.addChangeListener(this.handleChange);

  }

 

  componentWillUnmount() {

   DataSource.removeChangeListener(this.handleChange);

  }

 

  handleChange() {

   this.setState({

    data: selectData(DataSource, this.props)

   });

  }

 

  render() {

   // ... and renders the wrapped component with the fresh data!

   // Notice that we pass through any additional props

   return <WrappedComponent data={this.state.data} {...this.props} />;

  }

 };

} 

 HOC并沒有修改輸入的組件,也沒有使用繼承去重用它的行為。HOC只是一個(gè)函數(shù)。wrapped 組件接受了容器的所以props,同時(shí)還接受了一個(gè)新的prop(data),data用于渲染wrapped 組件的輸出。HOC不關(guān)心數(shù)據(jù)怎么使用也不關(guān)心數(shù)據(jù)為什么使用,wrapped組件不關(guān)心數(shù)據(jù)是哪兒得到。

因?yàn)閣ithSubscription只是一個(gè)常規(guī)的函數(shù),你能添加任意個(gè)數(shù)的參數(shù)。例如,你能讓data prop的名字是可配置的,從而進(jìn)一步將HOC與wrapped組件隔離。

或者接受一個(gè)配置shouldComponentUpdate,或者配置數(shù)據(jù)源的參數(shù)

使用高階組件時(shí)有些需要注意的地方。

1.不要修改原始組件,這一點(diǎn)很重要

有如下例子:

function logProps(InputComponent) {

 InputComponent.prototype.componentWillReceiveProps = function(nextProps) {

  console.log('Current props: ', this.props);

  console.log('Next props: ', nextProps);

 };

 // The fact that we're returning the original input is a hint that it has

 // been mutated.

 return InputComponent;

}

 

// EnhancedComponent will log whenever props are received

const EnhancedComponent = logProps(InputComponent); 

這里存在一些問題,1.輸入的組件不能與增強(qiáng)的組件單獨(dú)重用。2.如果給EnhancedComponent應(yīng)用其他的HOC,也會(huì)改變componentWillReceiveProps。

這個(gè)HOC對(duì)函數(shù)類型的組件不適用,因?yàn)楹瘮?shù)類型組件沒有生命周期函數(shù)HOC應(yīng)該使用合成代替修改——通過將輸入的組件包裹到容器組件中。

function logProps(WrappedComponent) {

 return class extends React.Component {

  componentWillReceiveProps(nextProps) {

   console.log('Current props: ', this.props);

   console.log('Next props: ', nextProps);

  }

  render() {

   // Wraps the input component in a container, without mutating it. Good!

   return <WrappedComponent {...this.props} />;

  }

 }

} 

這個(gè)新的logProps與舊的logProps有相同的功能,同時(shí)新的logProps避免了潛在的沖突。對(duì)class類型的組件和函數(shù)類型額組件同樣適用。

2.不要在render方法中使用HOCs

React的diff算法使用組件的身份去決定是應(yīng)該更新已存在的子樹還是拆除舊的子樹并裝載一個(gè)新的,如果從render方法中返回的組件與之前渲染的組件恒等(===),那么React會(huì)通過diff算法更新之前渲染的組件,如果不相等,之前渲染的子樹會(huì)完全卸載。 

render() {

 // A new version of EnhancedComponent is created on every render

 // EnhancedComponent1 !== EnhancedComponent2

 const EnhancedComponent = enhance(MyComponent);

 // That causes the entire subtree to unmount/remount each time!

 return <EnhancedComponent />;

} 

 在組件定義的外部使用HOCs,以至于結(jié)果組件只被創(chuàng)建一次。在少數(shù)情況下,你需要?jiǎng)討B(tài)的應(yīng)用HOCs,你該在生命周期函數(shù)或者構(gòu)造函數(shù)中做這件事

3.靜態(tài)方法必須手動(dòng)復(fù)制

有的時(shí)候在React組件上定義靜態(tài)方法是非常有用的。當(dāng)你給某個(gè)組件應(yīng)用HOCs,雖然原始組件被包裹在容器組件里,但是返回的新組件不會(huì)有任何原始組件的靜態(tài)方法。

// Define a static method

WrappedComponent.staticMethod = function() {/*...*/}

// Now apply an HOC

const EnhancedComponent = enhance(WrappedComponent);

 

// The enhanced component has no static method

typeof EnhancedComponent.staticMethod === 'undefined' // true 

 為了讓返回的組件有原始組件的靜態(tài)方法,就要在函數(shù)內(nèi)部將原始組件的靜態(tài)方法復(fù)制給新的組件。

function enhance(WrappedComponent) {

 class Enhance extends React.Component {/*...*/}

 // Must know exactly which method(s) to copy :(

  // 你也能夠借助第三方工具

 Enhance.staticMethod = WrappedComponent.staticMethod;

 return Enhance;

} 

 4.容器組件上的ref不會(huì)傳遞給wrapped component

雖然容器組件上的props可以很簡(jiǎn)單的傳遞給wrapped component,但是容器組件上的ref不會(huì)傳遞到wrapped component。如果你給通過HOCs返回的組件設(shè)置了ref,這個(gè)ref引用的是最外層容器組件,而非wrapped 組件

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • React18的useEffect執(zhí)行兩次如何應(yīng)對(duì)

    React18的useEffect執(zhí)行兩次如何應(yīng)對(duì)

    這篇文章主要給大家介紹了關(guān)于React18的useEffect執(zhí)行兩次如何應(yīng)對(duì)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用React具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-07-07
  • React如何利用Antd的Form組件實(shí)現(xiàn)表單功能詳解

    React如何利用Antd的Form組件實(shí)現(xiàn)表單功能詳解

    這篇文章主要給大家介紹了關(guān)于React如何利用Antd的Form組件實(shí)現(xiàn)表單功能的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • React Native AsyncStorage本地存儲(chǔ)工具類

    React Native AsyncStorage本地存儲(chǔ)工具類

    這篇文章主要為大家分享了React Native AsyncStorage本地存儲(chǔ)工具類,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • React Native中Mobx的使用方法詳解

    React Native中Mobx的使用方法詳解

    這篇文章主要給大家介紹了關(guān)于React Native中Mobx的使用方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-12-12
  • 詳解webpack2+React 實(shí)例demo

    詳解webpack2+React 實(shí)例demo

    本篇文章主要介紹了詳解webpack2+React 實(shí)例demo,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-09-09
  • react-dnd?API拖拽工具詳細(xì)用法示例

    react-dnd?API拖拽工具詳細(xì)用法示例

    這篇文章主要為大家介紹了react-dnd?API拖拽工具的詳細(xì)用法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • react中Hooks的理解和用法小結(jié)

    react中Hooks的理解和用法小結(jié)

    Hook是 React 16.8 的新增特性,它可以讓你在不編寫class的情況下使用state以及其他的React特性,這篇文章主要介紹了react中Hooks的理解和用法,需要的朋友可以參考下
    2023-05-05
  • 再次談?wù)揜eact.js實(shí)現(xiàn)原生js拖拽效果引起的一系列問題

    再次談?wù)揜eact.js實(shí)現(xiàn)原生js拖拽效果引起的一系列問題

    React 起源于 Facebook 的內(nèi)部項(xiàng)目,因?yàn)樵摴緦?duì)市場(chǎng)上所有 JavaScript MVC 框架,都不滿意,就決定自己寫一套,用來架設(shè) Instagram 的網(wǎng)站.本文給大家介紹React.js實(shí)現(xiàn)原生js拖拽效果,需要的朋友一起學(xué)習(xí)吧
    2016-04-04
  • React路由規(guī)則定義與聲明式導(dǎo)航及編程式導(dǎo)航分別介紹

    React路由規(guī)則定義與聲明式導(dǎo)航及編程式導(dǎo)航分別介紹

    這篇文章主要介紹了React路由規(guī)則的定義、聲明式導(dǎo)航、編程式導(dǎo)航,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-09-09
  • react反向代理使用http-proxy-middleware問題

    react反向代理使用http-proxy-middleware問題

    這篇文章主要介紹了react反向代理使用http-proxy-middleware問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07

最新評(píng)論

凉城县| 桐柏县| 彰武县| 瑞昌市| 上虞市| 扎赉特旗| 丹棱县| 工布江达县| 射阳县| 贺州市| 泸定县| 航空| 湘乡市| 新化县| 福贡县| 乌苏市| 宣化县| 碌曲县| 岫岩| 太仓市| 离岛区| 盐城市| 福海县| 灵宝市| 海伦市| 永年县| 东明县| 苗栗市| 祁东县| 花莲县| 合川市| 寿阳县| 兰溪市| 永新县| 沙湾县| 罗源县| 九龙县| 彰武县| 绵竹市| 恩平市| 陆河县|