Grid是一個窗口網格。Grid網格只根據當前的水平/垂直滾動位置渲染填充自身所需的單元格。react
Props瀏覽器
屬性 | 類型 | 必選? | 描述 |
---|---|---|---|
autoContainerWidth | Boolean | 否 | 將內部可滾動的容器寬度設爲自動。 |
autoHeight | Boolean | 否 | Grid外部的高度設置爲自動。這個屬性只能和WindowScroller高階組件結合使用 |
autoWidth | Boolean | 否 | Grid外部的寬度設置爲自動。這個屬性只能和WindowScroller高階組件結合使用 |
cellRangeRenderer | Function | 否 | 負責渲染一組給定索引範圍的單元格 |
cellRenderer | Function | 是 | 負責渲染給定行列索引的單元格 |
className | String | 否 | 可選的自定義CSS類名,附加到根Grid元素上 |
columnCount | Number | 是 | 網格列的數量 |
columnWidth | Number or Function | 是 | 一個固定的列寬(數字)或一個函數返回給定索引(({index: number}): number)的列寬。若使用函數,能夠指定estimatedColumnSize來優化滾動行爲。 |
containerProps | Object | 否 | 負責添加屬性到cell-container(例如onWheel事件) |
containerRole | String | 否 | cell-ContainerARIA角色,默認是rowgroup |
containerStyle | Object | 否 | 可選的自定義行內樣式附加內部的cell-container元素 |
deferredMeasurementCache | CellMeausrer | 否 | 若CellMeasure用於計算Grid的子元素,該屬性必須是CellMeausrerCache的指針。一個共享的CellMeasurerCache引用使Grid和CellMeasurer共享計算數據 |
estimatedColumnSize | Number | 否 | 用於在全部列被計算以前預估整個Grid的寬度。被預估的整寬會在列渲染後調整 |
estimatedRowSize | Number | 否 | 用於在全部行被計算以前預估整個Grid的高度。被預估的整高會在行渲染後調整 |
height | Number | 是 | Grid的高度;該屬性決定了可見的行數量 |
id | String | 否 | 可選的自定義ID來附加到根Grid元素 |
isScrolling | Boolean | 否 | 重寫內部是否處於滾動的狀態,整個屬性主要服務於WindowScroller組件 |
isScrollingOptOut | Boolean | 否 | 防止在滾動端從新渲染可見單元格 |
onContentRenderer | Function | 否 | 使用剛渲染的Grid區域的信息調用回調函數,旨在可見行發生改變時調用:({columnOverscanStartIndex: number, columnOverscanStopIndex: number, columnStartIndex: number, columnStopIndex: number, rowOverscanStartIndex: number, rowOverscanStopIndex: number, rowStartIndex: number, rowStopIndex: number}): void |
onScroll | Function | 否 | 每當內部可滾動區域內的滾動偏移發生變化時,將調用回調:({ clientHeight: number, clientWidth: number, scrollHeight: number, scrollLeft: number, scrollTop: number, scrollWidth: number }): void |
onScrollbarPresenceChange | Function | 否 | 每當添加或移除水平或垂直滾動條時調用:({ horizontal: boolean, size: number, vertical: boolean }): void |
overscanColumnCount | Number | 否 | 渲染可見的網格切片先後的列數量。能夠減小在某些瀏覽器或設備滾動期間的閃爍。 |
overscanIndicesGetter | Function | 否 | 負責計算在指定範圍以前和以後要掃描的單元格數量 |
overscanRowCount | Number | 否 | 渲染可見的網格切片先後的行數量。能夠減小在某些瀏覽器或設備滾動期間的閃爍。 |
role | String | 否 | 可選的重寫默認ARIA,默認是grid |
rowCount | Number | 是 | 網格中行的數量 |
rowHeight | Number or Function | 是 | 固定的行高(數字)或一個函數返回給定索引的行高:({index: nmber}): number。若是使用函數,指定estimatedRowSize來優化滾動行爲 |
scrollingResetTimeInterval | Number | 否 | 在上一次滾動事件以後等待此時間,而後重置網格指針事件;默認爲150ms。 |
scrollLeft | Number | 否 | 水平偏移量 |
scrollToAlignment | String | 否 | 控制scrolled-to-cells的對齊方式。默認(自動)滾動到可能的最小數量確保指定單元格徹底可見。使用start將指定單元格對其到網格左上,使用end對齊到右下。使用center將指定單元格對其到容器中間。 |
scrollToColumn | Number | 否 | 確保可見的列索引(必要時強行滾動),優先於scrollLeft |
scrollToRow | Number | 否 | 確保可見的行索引。優先於scrollTop |
scrollTop | Number | 否 | 垂直偏移量 |
style | Object | 否 | 可選的自定義內聯樣式,附加到根Grid元素 |
tabIndex | Number | 否 | 可選的重寫默認的標籤索引。默認是0 |
width | Nubmer | 是 | Grid的寬度,這個屬性決定了可見的列的數量 |
公共方法緩存
獲取給定單元格的偏移量和對齊方式。安全
獲取預估的整行高度。app
獲取預估的整列寬度dom
此方法處理源於外部滾動控件的滾動事件。這是一種高級方法,除非您要實現自定義滾動條解決方案,不然可能不該該使用它。ide
預計算全部Grid中的行和列。函數
在指定索引後(默認是0)從新計算行高和列寬。佈局
若是動態列或行的大小改變,但沒有其餘更改,則應調用此函數。由於Grid只接受columnCount和rowCount,它沒法檢測基礎數據什麼時候更改。性能
此方法還將強制執行渲染週期(經過forceUpdate),以確保更新的測量值反映在渲染的網格中。
確保行和列可見。這個方法可被用來當用戶滾動遠離某個單元格以後,安全地滾回到原處。即便已經滾動到了改位置。
滾動指定偏移量。用於設置位置變化的動畫。
類名
Grid組件支持下列靜態類名:
屬性 | 描述 |
---|---|
ReactVirtualized__Grid | (外部)主要元素 |
ReactVirtualizedGridinnerScrollContainer | 內部滾動區域 |
cellRangeRenderer
這是一個高級屬性。當網格須要其餘覆蓋的UI(例如甘特圖或日曆應用程序)的狀況下,它頗有用。使用onScroll回調或ScrollSync 高階組件能夠更輕鬆地解決許多用例。
若是你想重寫cellRangeRenderer,最簡單的方法是加強默認的實現:
import {defaultCellRangeRenderer, Grid} from 'react-virtualized';function cellRangeRenderer(props) { const children = defaultCellRangeRenderer(props); children.push(<div>My custom overlay</div>); return children; }function CustomizedGrid(props) { return <Grid cellRangeRenderer={cellRangeRenderer} {...props} />; }複製代碼
若是須要更大的自定義,則可能須要派生defaultCellRangeRenderer函數。
該函數接受如下命名參數:
function cellRangeRenderer({ cellCache, // Temporary cell cache used while scrolling cellRenderer, // Cell renderer prop supplied to Grid columnSizeAndPositionManager, // @see CellSizeAndPositionManager, columnStartIndex, // Index of first column (inclusive) to render columnStopIndex, // Index of last column (inclusive) to render horizontalOffsetAdjustment, // Horizontal pixel offset (required for scaling) isScrolling, // The Grid is currently being scrolled rowSizeAndPositionManager, // @see CellSizeAndPositionManager, rowStartIndex, // Index of first row (inclusive) to render rowStopIndex, // Index of last row (inclusive) to render scrollLeft, // Current horizontal scroll offset of Grid scrollTop, // Current vertical scroll offset of Grid styleCache, // Temporary style (size & position) cache used while scrolling verticalOffsetAdjustment, // Vertical pixel offset (required for scaling) }) { const renderedCells = []; for (let rowIndex = rowStartIndex; rowIndex <= rowStopIndex; rowIndex++) {// This contains :offset (top) and :size (height) information for the celllet rowDatum = rowSizeAndPositionManager.getSizeAndPositionOfCell(rowIndex);for ( let columnIndex = columnStartIndex; columnIndex <= columnStopIndex; columnIndex++ ) { // This contains :offset (left) and :size (width) information for the cell let columnDatum = columnSizeAndPositionManager.getSizeAndPositionOfCell( columnIndex, ); // Be sure to adjust cell position in case the total set of cells is too large to be supported by the browser natively. // In this case, Grid will shift cells as a user scrolls to increase cell density. let left = columnDatum.offset + horizontalOffsetAdjustment; let top = rowDatum.offset + verticalOffsetAdjustment; // The rest of the information you need to render the cell are contained in the data. // Be sure to provide unique :key attributes. let key = `${rowIndex}-${columnIndex}`; let height = rowDatum.size; let width = columnDatum.size; // Now render your cell and additional UI as you see fit. // Add all rendered children to the :renderedCells Array.} } return renderedCells; }複製代碼
overscanIndicesGetter
這是一個高級屬性。這個函數負責計算指定範圍先後掃描的單元格數量。默認下react-virtualized根據滾動方向優化了掃描的單元數。若是你想自定義這個行爲,能夠forkdefaultOverscanIndicesGetter函數。
function overscanIndicesGetter ({ direction, // One of "horizontal" or "vertical" cellCount, // Number of rows or columns in the current axis scrollDirection, // 1 (forwards) or -1 (backwards) overscanCellsCount, // Maximum number of cells to over-render in either direction startIndex, // Begin of range of visible cells stopIndex // End of range of visible cells }) { return {overscanStartIndex: Math.max(0, startIndex - overscanCellsCount),overscanStopIndex: Math.min(cellCount - 1, stopIndex + overscanCellsCount) } }複製代碼
cellRender
負責渲染單個單元格,給出了行列的索引。此函數接受下列命名參數:
function cellRenderer({ columnIndex, // Horizontal (column) index of cell isScrolling, // The Grid is currently being scrolled isVisible, // This cell is visible within the grid (eg it is not an overscanned cell) key, // Unique key within array of cells parent, // Reference to the parent Grid (instance) rowIndex, // Vertical (row) index of cell style, // Style object to be applied to cell (to position it); // This must be passed through to the rendered cell element. }) { // Grid data is a 2d array in this example... const user = list[rowIndex][columnIndex]; // If cell content is complex, consider rendering a lighter-weight placeholder while scrolling. const content = isScrolling ? '...' : <User user={user} />; // Style is required since it specifies how the cell is to be sized and positioned. // React Virtualized depends on this sizing/positioning for proper scrolling behavior. // By default, the grid component provides the following style properties: // position // left // top // height // width // You can add additional class names or style properties as you would like. // Key is also required by React to more efficiently manage the array of cells. return (<div key={key} style={style}> {content}</div> ); }複製代碼
基礎的Grid示例
下面是一個很是基礎的Grid示例。這個網格展現了一組隊具備固定行列大小的對象。(也支持動態的)。
import React from 'react';import ReactDOM from 'react-dom';import {Grid} from 'react-virtualized';// Grid data as an array of arraysconst list = [ ['Brian Vaughn', 'Software Engineer', 'San Jose', 'CA', 95125 /* ... */], // And so on...];function cellRenderer({columnIndex, key, rowIndex, style}) { return (<div key={key} style={style}> {list[rowIndex][columnIndex]}</div> ); }// Render your gridReactDOM.render( <GridcellRenderer={cellRenderer}columnCount={list[0].length}columnWidth={100}height={300}rowCount={list.length}rowHeight={30}width={300} />, document.getElementById('example'), );複製代碼
CellMeasurer是經過一種用戶不可見的渲染方式自動計算單元格內容的高階組件。能夠指定一個固定的寬度來計算動態的高度(反之亦然)。這是一個高級的組件,但具備一些侷限性和性能方面的注意事項。
CellMeasurer能夠和Grid,List和Table這些組件一塊兒使用,但不能夠和Collection一塊兒使用。
Props
屬性 | 類型 | 必選? | 描述 |
---|---|---|---|
cache | CellMeasurerCache | 是 | 在CellMeasure和他們的父級Grid之間共享的緩存 |
children | Element or Function | 是 | 能夠是一個React元素(例如<div />)或者一個函數 (例如({measure, registerChild}) => <div ref={registerChild} />) |
columnIndex | number | 是 | 經計算的列index(在父級Grid裏)或者0(使用List或Table) |
parent | Grid | 是 | 父級Grid的引用;改值是由Grid傳遞給cellRenderer,應該原樣傳遞 |
rowIndex | number | 是 | 經計算的行index(在父級Grid裏) |
Render Props
屬性 | 類型 | 描述 |
---|---|---|
measure | Function | 執行單元格計算 |
registerChild | Function | 指定要計算的Dom元素,能夠被用做爲ref(默認是WindowScroller使用ReactDOM.findDOMNode函數) |
CellMeasurerCache
CellMeasurerCache存儲了CellMeasurer的計算而且將他們共享與一個父級Grid。應當基於你所須要的計算類型來配置。接受如下參數:
屬性 | 類型 | 必選? | 描述 |
---|---|---|---|
defaultHeight | number | 否 | 未計算的單元格將改值初始化高度 |
defaultWidth | number | 否 | 未計算的單元格將改值初始化寬度 |
fixedHeight | number | 否 | 渲染單元格將擁有一個固定的高度,動態的寬度 |
fixedWidth | number | 否 | 渲染單元格將擁有一個固定的寬度,動態的高度 |
minHeight | number | 否 | 多個單元格的派生行高度不該該小於改值 |
minWidth | number | 否 | 多個單元格的派生列寬度不該該小於改值 |
keyMapper | number | 否 | 能夠更智能地將給定的列和行索引映射到項目ID。這樣能夠防止在修改其父級時單元格緩存失效。(rowIndex: number, columnIndex: number) => any |
注意上述全部屬性都是可選的,你必須至少提供其中一些。CellMeasureerCache並不意味着同時計算動態地寬度和高度。當行(或列)的大小等於這個行最大單元格的大小時這樣作會十分低效。
CellMeasurerCache通用的方法
重置一個指定單元格的計算緩存
應當在單元格須要從新計算來處理動態地內容時調用。(例如用加載的內容替換加載圖標或對有狀態單元的狀態變化作出響應)
重置全部單元格的計算緩存
應當在Grid,List,Table組件因使用響應式佈局觸發resize事件須要迴流內容的時候調用。(例如修改窗口大小時須要一個單元格高度的響應)
例子
這個例子展現了固定行高動態列寬的Grid。
import React from 'react';import { CellMeasurer, CellMeasurerCache, Grid } from 'react-virtualized';// In this example, average cell width is assumed to be about 100px.// This value will be used for the initial `Grid` layout.// Cell measurements smaller than 75px should also be rounded up.// Height is not dynamic.const cache = new CellMeasurerCache({ defaultWidth: 100, minWidth: 75, fixedHeight: true});function cellRenderer ({ columnIndex, key, parent, rowIndex, style }) { const content // Derive this from your data somehow return (<CellMeasurer cache={cache} columnIndex={columnIndex} key={key} parent={parent} rowIndex={rowIndex}> <divstyle={{ ...style, height: 35, whiteSpace: 'nowrap' }} >{content} </div></CellMeasurer> ); }function renderGrid (props) { return (<Grid {...props} columnWidth={cache.columnWidth} deferredMeasurementCache={cache} cellRenderer={cellRenderer}/> ); }複製代碼
CellMeasurer默認使用findDOMNode來獲取到DOM元素去計算。但這個API在React嚴格模式下是不推薦的。因此你可能想要避免這個用法。做爲代替,你可使用registerChild屬性來指定元素。(例如將他做爲一個ref傳入)
import React from 'react';import { CellMeasurer, CellMeasurerCache, Grid } from 'react-virtualized';// In this example, average cell width is assumed to be about 100px.// This value will be used for the initial `Grid` layout.// Cell measurements smaller than 75px should also be rounded up.// Height is not dynamic.const cache = new CellMeasurerCache({ defaultWidth: 100, minWidth: 75, fixedHeight: true});function cellRenderer ({ columnIndex, key, parent, rowIndex, style }) { const content // Derive this from your data somehow return (<CellMeasurer cache={cache} columnIndex={columnIndex} key={key} parent={parent} rowIndex={rowIndex}> {({registerChild}) => (<div style={{...style,height: 35,whiteSpace: 'nowrap' }} > {content}</div> )}</CellMeasurer> ); }function renderGrid (props) { return (<Grid {...props} columnWidth={cache.columnWidth} deferredMeasurementCache={cache} cellRenderer={cellRenderer}/> ); }複製代碼
本示例說明如何將CellMeasurer組件與List組件一塊兒使用,以顯示動態高度行。與上述實例不一樣在於:行高是由圖片數據加載完成後決定的。爲此將一個函數傳入CellMeasurer組件,接受measure和registerChild兩個參數。measure應在單元格內容計算完後調用。(本例中爲圖片數據加載完成後)
import React from 'react';import { CellMeasurer, CellMeasurerCache, List } from 'react-virtualized';// In this example, average cell height is assumed to be about 50px.// This value will be used for the initial `Grid` layout.// Width is not dynamic.const cache = new CellMeasurerCache({ defaultHeight: 50, fixedWidth: true});function rowRenderer ({ index, isScrolling, key, parent, style }) { const source // This comes from your list data return (<CellMeasurer cache={cache} columnIndex={0} key={key} parent={parent} rowIndex={index}> {({ measure, registerChild }) => ( // 'style' attribute required to position cell (within parent List)<div ref={registerChild} style={style}> <imgonLoad={measure}src={source} /></div> )}</CellMeasurer> ); }function renderList (props) { return (<List {...props} deferredMeasurementCache={cache} rowHeight={cache.rowHeight} rowRenderer={rowRenderer}/> ); }複製代碼
// Normally, every cell gets measured individually and is very slow.// However, with the keyMapper prop we can specify a constant return value and// tell CellMeasurer that all measurements after the first one will hit the// cache and we get a speedy solution.const cache = new CellMeasurerCache({ defaultHeight: 30, fixedWidth: true, keyMapper: () => 1, });複製代碼
侷限性和性能事項
計算列寬須要計算全部行來決定該列發生的最大寬度。計算行高亦如此。所以當列和單元格同時包含龐大的數據時,使用這個Grid的高階組件並非一個好的主意。
因爲該組件一次只計算一個單元格的寬高,因此若是用戶用滾動條或者scoll-to-cell屬性一次性跳過許多行(或列)時將會卡慢。不幸的是如今沒有針對該性能侷限性的解決方案。