zoukankan      html  css  js  c++  java
  • [React] React Virtual

    // 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,
       '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
  • 相关阅读:
    JAVA 框架
    npm安装超时,使用淘宝镜像
    使用vite搭建Vue3项目
    前端常用框架
    vue发布自己的组件库-vue3
    vue2升级vue3-基础教程
    Navicat Premium 15破解失败解决方案
    大屏
    vue使用高德地图
    vue生命周期及钩子函数
  • 原文地址:https://www.cnblogs.com/Answer1215/p/13861798.html
Copyright © 2011-2022 走看看