码迷,mamicode.com
首页 > 其他好文 > 详细

[React] React Virtual

时间:2020-10-24 11:42:42      阅读:24      评论:0      收藏:0      [点我收藏+]

标签:key   cer   ref   highlight   cal   mat   virtual   find   change   

// Window large lists with react-virtual
// http://localhost:3000/isolated/final/04.js

import React from ‘react‘
import {useVirtual} from ‘react-virtual‘
import {useCombobox} from ‘../use-combobox‘
import {getItems} from ‘../workerized-filter-cities‘
import {useAsync, useForceRerender} from ‘../utils‘

const getVirtualRowStyles = ({size, start}) => ({
  position: ‘absolute‘,
  top: 0,
  left: 0,
  width: ‘100%‘,
  height: size,
  transform: `translateY(${start}px)`,
})

function Menu({
  items,
  getMenuProps,
  getItemProps,
  highlightedIndex,
  selectedItem,
  listRef,
  virtualRows,
  totalHeight,
}) {
  return (
    <ul {...getMenuProps({ref: listRef})}>
      <li style={{height: totalHeight}} /> // The reason here add a li is tell react virtual, the total height of the items, so the scolling bar can display correct size
      {virtualRows.map(({index, size, start}) => {
        const item = items[index]
        if (!item) return null
        return (
          <ListItem
            key={item.id}
            getItemProps={getItemProps}
            item={item}
            index={index}
            isSelected={selectedItem?.id === item.id}
            isHighlighted={highlightedIndex === index}
            style={getVirtualRowStyles({size, start})}
          >
            {item.name}
          </ListItem>
        )
      })}
    </ul>
  )
}

function ListItem({
  getItemProps,
  item,
  index,
  isHighlighted,
  isSelected,
  style,
  ...props
}) {
  return (
    <li
      {...getItemProps({
        index,
        item,
        style: {
          backgroundColor: isHighlighted ? ‘lightgray‘ : ‘inherit‘,
          fontWeight: isSelected ? ‘bold‘ : ‘normal‘,
          ...style,
        },
        ...props,
      })}
    />
  )
}

function App() {
  const forceRerender = useForceRerender()
  const [inputValue, setInputValue] = React.useState(‘‘)

  const {data: items, run} = useAsync({data: [], status: ‘pending‘})
  React.useEffect(() => {
    run(getItems(inputValue))
  }, [inputValue, run])

  const listRef = React.useRef()

  const rowVirtualizer = useVirtual({
    size: items.length,
    parentRef: listRef,
    estimateSize: React.useCallback(() => 20, []),
    overscan: 10,
  })

  const {
    selectedItem,
    highlightedIndex,
    getComboboxProps,
    getInputProps,
    getItemProps,
    getLabelProps,
    getMenuProps,
    selectItem,
  } = useCombobox({
    items,
    inputValue,
    onInputValueChange: ({inputValue: newValue}) => setInputValue(newValue),
    onSelectedItemChange: ({selectedItem}) =>
      alert(
        selectedItem
          ? `You selected ${selectedItem.name}`
          : ‘Selection Cleared‘,
      ),
    itemToString: item => (item ? item.name : ‘‘),
    scrollIntoView: () => {},
    onHighlightedIndexChange: ({highlightedIndex}) =>
      highlightedIndex !== -1 && rowVirtualizer.scrollToIndex(highlightedIndex),
  })

  return (
    <div className="city-app">
      <button onClick={forceRerender}>force rerender</button>
      <div>
        <label {...getLabelProps()}>Find a city</label>
        <div {...getComboboxProps()}>
          <input {...getInputProps({type: ‘text‘})} />
          <button onClick={() => selectItem(null)} aria-label="toggle menu">
            &#10005;
          </button>
        </div>
        <Menu
          items={items}
          getMenuProps={getMenuProps}
          getItemProps={getItemProps}
          highlightedIndex={highlightedIndex}
          selectedItem={selectedItem}
          listRef={listRef}
          virtualRows={rowVirtualizer.virtualItems}
          totalHeight={rowVirtualizer.totalSize}
        />
      </div>
    </div>
  )
}

export default App

 

[React] React Virtual

标签:key   cer   ref   highlight   cal   mat   virtual   find   change   

原文地址:https://www.cnblogs.com/Answer1215/p/13861798.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!