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

React高階用法之Render Props

開發
最近會陸續分享我在使用React的過程總結的一些比較高階的使用方法,這些方法可以提升代碼的可復用性,也讓代碼看起來更加簡潔明晰。今天要講的是Render Props,很多人可能都知道react的這個特性,但在實際項目中不知道如何用起來。剛好這兩天的一個項目中用到了它,所以借機分享一下。

 什么是Render Props
“render prop”是指一種在React組件之間使用值為函數的prop共享代碼的技術

這個概念聽上去有點拗口,我們拆開了看它。

首先它本質上是一個prop,是用來父子組件之間傳遞數據用的
其次這個prop傳遞的值是一個函數
最后它取名render props,是因為它通常是用來render(渲染)某個元素或組件
比如官網給出的示例:

 

  1. <DataProvider render={data => ( 
  2.   <h1>Hello {data.target}</h1> 
  3. )}/> 

我們給 這個子組件傳遞了一個叫 render 的prop,這個prop的值是一個函數,它返回了一個 h1 元素。然后我們可以假裝實現一下這個 組件:

 

  1. class DataProvider extends React.Component { 
  2.     state = { 
  3.         data: { 
  4.             target: 'World' 
  5.         } 
  6.     } 
  7.     render() { 
  8.         return this.props.render(this.state) 
  9.     } 

最終我們的 DataProvider 組件渲染的結果就是 <h1>Hello World</h1> 。有同學可能會有疑問,為什么要費這么大周折?直接把 h1 元素寫在 DataProvider 組件里不也可以嗎?

這里就要講到代碼的可復用性了,假如下次我們希望 DataProvider 組件渲染的結果就是 Hello World 呢?難道又去修改 DataProvider 組件嗎?有了render props,我們就可以動態地決定 DataProvider 組件內部要渲染的元素,同時這個元素還可以使用到 DataProvider 組件內部的數據。

實際項目案例
下面講一個實際的項目案例,下圖中我們有一個橫向滾動的 ScrollView 組件,這個組件本身是個很普通的

元素, 只不過樣式上加了 overflow-x: scroll 所以可以橫向滾動起來。產品同學說滾動區域的下方要有進度點指示,從而告訴用戶總共有幾個產品,已經現在滾到第幾個產品了。

 

明確了產品需求以后,我們就開始來實現,首先看下第一版:

 

  1. class demo extends Component { 
  2.     state = { 
  3.       activeIndicator: 0, 
  4.       list: [] 
  5.     } 
  6.      
  7.     onScroll = () => { 
  8.         const { list } = this.state; 
  9.         const container = findDOMNode(this.refs.container); 
  10.         ... 
  11.         const itemVisibleLengthInContainer = list.map((item, index) => { 
  12.           const node = findDOMNode(this.refs[`item-${index}`]); 
  13.            ... 
  14.         }); 
  15.         this.setState({ 
  16.           activeIndicator: active, 
  17.         }); 
  18.     }; 
  19.      
  20.     render() { 
  21.         const { list, activeIndicator } = this.state; 
  22.         return ( 
  23.              <ScrollView 
  24.                 ref="container" 
  25.                 horizontal={true
  26.                 onScroll={this.onScroll} 
  27.              > 
  28.                 {list.map((item,i) => ( 
  29.                     <ProductItem 
  30.                         ref={`item-${i}`} 
  31.                         data={item} 
  32.                     /> 
  33.                  ))} 
  34.                   
  35.              </ScrollView> 
  36.              <Indicator list={list} active={activeIndicator} /> 
  37.         ) 
  38.     } 

ok,需求我們已經實現了。實現邏輯就是給 ScrollView 組件添加一個 onScroll 事件,每當滾動的時候,會先計算 ScrollView 容器的位置信息,和每一個 ProductItem 的位置信息,算出現在哪個 ProductItem 在 ScrollView 容器中所占比例最高,從而得出現在應該高亮的 activeIndicator 。

不過現在有個問題哦,給 ScrollView 組件增加進度指示器這個功能,更像是 ScrollView 組件應該支持的一個功能,而不是直接寫在業務代碼里。所以我們應該提供一個新組件 ScrollViewWithIndicator ,讓它去處理進度指示器的問題,從而跟業務解耦。

 

  1. class ScrollViewWithIndicator extends Component { 
  2.     state = { 
  3.       activeIndicator: 0, 
  4.     } 
  5.      
  6.     onScroll = () => { 
  7.         const { list } = this.props; 
  8.         const container = findDOMNode(this.refs.container); 
  9.         ... 
  10.         const itemVisibleLengthInContainer = list.map((item, index) => { 
  11.           const node = findDOMNode(this.refs[`item-${index}`]); 
  12.            ... 
  13.         }); 
  14.         this.setState({ 
  15.           activeIndicator: active, 
  16.         }); 
  17.     }; 
  18.      
  19.     render() { 
  20.         const [{ list, children, ...restProps } , { activeIndicator }] = [this.props, this.state]; 
  21.         return ( 
  22.              <ScrollView 
  23.                 ref="container" 
  24.                 {...restProps} 
  25.                 onScroll={this.onScroll} 
  26.              > 
  27.                 {list.map((item,i) => ( 
  28.                     <div ref={`item-${i}`}>    
  29.                         {children(item} 
  30.                     </div> 
  31.                  ))} 
  32.                   
  33.              </ScrollView> 
  34.              <Indicator list={list} active={activeIndicator} /> 
  35.         ) 
  36.     } 

然后我們的業務代碼就可以簡化了:

 

  1. class demo extends Component { 
  2.     state = { 
  3.       list: [] 
  4.     } 
  5.     render() { 
  6.         const { list } = this.state; 
  7.         return ( 
  8.               <ScrollViewWithIndicator 
  9.                 horizontal={true
  10.                 list={list} 
  11.              > 
  12.               {child => <ProductItem {...child} />}  //(*) 
  13.              </ScrollViewWithIndicator> 
  14.         ) 
  15.     } 

仔細看業務代碼demo組件,我們一共給ScrollViewWithIndicator組件傳遞了多少個props?答案是三個!分別是horizontal, list ,children,大家千萬別忘了this.props.children也是一個props哦

再仔細看第(*)這句話,我們給ScrollViewWithIndicator組件傳遞一個叫children的prop,同時這個prop是一個函數,返回了一個組件(元素),這就是我們所說的render props啊

為什么list.map這個數組的遍歷要寫在ScrollViewWithIndicator組件內部,而不是業務組件demo里呢?因為我們在onScroll 事件回調函數里要計算每一個商品item的位置,也就是要拿到商品item的ref屬性,所以把數組的遍歷寫在ScrollViewWithIndicator 組件內部方便我們顯性給每一個商品item聲明ref屬性

 

責任編輯:姜華 來源: 晨曦大前端
相關推薦

2020-10-27 09:50:06

Reactrende前端

2020-10-25 07:49:37

React組件

2024-06-05 08:29:35

2017-05-16 15:32:15

2024-06-14 07:47:37

2021-09-01 18:42:57

React Props組件

2025-03-06 11:07:27

2016-08-12 13:55:06

2019-10-28 09:11:53

MySQL性能優化

2021-08-02 08:34:20

React性能優化

2021-07-07 08:36:45

React應用場景

2020-06-22 15:41:20

IF函數Excel用法

2023-11-01 17:57:56

React應用程序性能

2022-03-16 17:01:35

React18并發的React組件render

2020-12-20 10:02:17

ContextReactrender

2023-04-20 10:15:57

React組件Render

2019-10-29 15:28:40

Refs組件前端

2024-06-21 09:44:52

.NET配置文件NuGet 包

2024-02-01 00:10:21

C++PIMPL編程

2022-08-04 08:17:27

React高階組件
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 999热视频| 日韩一区二| 精品网 | 一区二区三区国产精品 | 精品国产乱码 | 久久免费精品 | 久久久国产精品一区 | 亚洲男女视频在线观看 | 国产在线精品一区二区 | 天天干干 | 日日日色 | 狠狠的干 | 日日摸天天添天天添破 | 精品福利视频一区二区三区 | 成人片免费看 | 成人精品视频在线 | 国产成人一区二 | 黄色片视频 | 九九热精品视频 | 国产中文区二幕区2012 | 精品久久99 | 日本中文在线 | 天天干成人网 | 国产色视频网站 | 中文字幕动漫成人 | 亚洲一区二区三区在线播放 | 麻豆毛片| 精品欧美一区二区精品久久久 | 色综合99| 亚洲一区二区三区在线 | 一级a爱片久久毛片 | 久久91精品久久久久久9鸭 | 亚洲一区二区在线 | 亚洲国产成人在线视频 | 欧美11一13sex性hd| 亚洲国产精品精华素 | 日韩专区中文字幕 | 在线播放中文字幕 | 日韩av一区在线观看 | 欧洲精品视频一区 | 中文字幕亚洲一区二区三区 |