react-virtualized实现高效虚拟滚动,并快速定位到当前位置(类似手机通讯录)
1、官方参考
https://github.com/bvaughn/react-virtualized/blob/master/docs/List.md
2、效果
安装
<= raact16 npm install react-virtualized --save
>= react17 npm install react-virtualized --legacy-peer-deps
3、App.tsx
import React, { useState, useRef } from 'react' import { List, AutoSizer } from 'react-virtualized' import './App.css' const App = () => { const [state, setState] = useState<any>({ activeIndex: 0 }) const ListRef = useRef<any>() const list = ['0---d5ed3a75-8ee8-ce0c-59bb-d19e14e6380dreVir', '1---34d327d5-72fb-e630-af17-22ba4acbb2c0reVir', '2---6351dfa1-ca7b-1910-f2eb-0ed74ce278f4reVir', '3---218eb1dd-d28b-bb17-4186-fc2ffcf388c5reVir', '4---16477234-95fe-0dfa-6674-016336fddd7dreVir', '5---1d8ccc45-80ca-dc0e-7441-5c01a3199cb9reVir', '6---d840c2d7-47e5-bcd8-a7c7-e0a5a848bb0creVir', '7---1b586517-d225-a229-9d9b-104119cb84c1reVir', '8---ca6da4f2-5311-446f-aabf-9fc2f08d0897reVir', '9---81ecf535-0456-89a6-ff3e-c170082ea362reVir', '10---029aac2c-d3b2-76a3-e16d-6cecb0403ef8reVir', '11---ec53f984-6d61-5d84-3480-025b31cd0a79reVir', '12---b48330e5-ac1f-71b5-7174-85cb8b8c6005reVir', '13---c7ab4f3f-5675-6223-9cc9-a985d89dd088reVir', '14---1852a63d-2432-9524-8695-00ac01eba2careVir', '15---4c834f36-367a-23e2-5231-0ca71df6d61dreVir', '16---352384c3-34ef-00ff-34f3-6b56410da62breVir', '17---a35accef-1ec3-4299-4413-0cce95269a1freVir', '18---740affec-d008-5b1a-4b49-4c09f2083e09reVir', '19---146e4a1f-b78c-a5d3-bd77-1eef839081f0reVir', '20---50b2c4b1-04c1-12e1-747a-565b8dc8b3abreVir', '21---dfdd8d73-79a5-7f24-48b0-0e0de9df12d1reVir', '22---13993aa8-162c-84cc-6fc8-00fcfe47e5d9reVir', '23---c4ec5a5a-91ba-70b4-0126-75a007fdbf56reVir', '24---4575c0da-840c-bac9-0987-7fdc18830a90reVir', '25---0c144a4d-4ec1-c900-5684-80d26afbefcereVir', '26---6ddf15f5-78cc-46df-b650-ec4025cddd90reVir', '27---5a9b5a70-97a4-f2a7-c0f9-dbd9a9f21ff6reVir', '28---c9f26efa-0ab2-97ad-45a0-fe36eab2cfd6reVir', '29---8b6e376e-7bcc-8c12-7644-779322183affreVir', '30---a2ca1daa-404e-ec42-6b0f-aad949b66549reVir', '31---b62b8aea-e79c-2f99-db01-a49f6ae96074reVir', '32---db3324b4-4eb5-5fe6-6804-7cbc8387f526reVir', '33---402758f8-e586-29d5-2900-54e13efb58dbreVir', '34---a73404df-5282-85c9-c6f5-7cf6b9d3b717reVir', '35---2ac1f9c9-8081-5c75-5dbb-202d57903bd6reVir', '36---778c6d67-d5f4-6a7b-1b65-b6c155057a75reVir', '37---87f2b1c2-c664-4f5f-d9f1-f8f4b7e975abreVir', '38---3d928878-12b1-3e86-b8c7-cabe0b895515reVir', '39---2d95c6bf-8548-afae-2ea3-6e00b200634breVir', '40---db52b2bd-f21d-23fd-7ec6-5cf20f85f9dfreVir', '41---3d466991-0c16-357a-6e92-a74f38b95cccreVir', '42---ab9010bb-0034-e6a9-dbc3-815eaf30eb6creVir', '43---f17976c7-b946-1094-21bc-2cd248fc6db0reVir', '44---0346e288-273a-ddcd-c50f-20e930aa1f9dreVir', '45---649c4938-6fba-83cc-3503-1aaf7bd5a62breVir', '46---4ae99950-6018-387b-bad1-4870d87a807freVir', '47---02794df6-05fb-b731-7d18-dfc60201d607reVir', '48---3f84dccc-ccf0-709a-c4f2-5bccda54210freVir', '49---863c744d-7d23-2950-46ff-377b6372e530reVir', '50---c7f87285-a8bc-80c1-7afc-f375d93ae3ffreVir', '51---be505ac4-d1d2-6fb4-bfc2-e8d7b28f428ereVir', '52---0ff97e8b-d8d1-a8af-09c5-1e1a30d71684reVir', '53---af1d29eb-2980-aa28-da2a-b909ff6e87a0reVir', '54---d86f6bee-1549-7e27-1994-2e912450576ereVir', '55---bf6933ef-8095-0cbd-0b5b-0883b824221areVir', '56---441f5aa6-3c01-3847-e1eb-8214f540716creVir', '57---75689481-2853-e606-1e74-1698af422fcareVir', '58---218d7662-aba1-6744-8558-caa9a7f3e4fcreVir', '59---80409e16-621a-3332-2ef2-67bf2ff06564reVir', '60---74c55d91-97a5-22ac-9615-2ae2bb7658aareVir', '61---a4df2a1d-26f2-1449-8f9a-f1211ff50647reVir', '62---6629f592-893b-6ede-5f3c-f04bf394fe87reVir', '63---3c91c35c-7ab2-29e4-b071-d29e3d14dfd2reVir', '64---4b82e18e-3b29-cb1f-240f-fccb2dccbf52reVir', '65---e89aab64-22b0-5ed1-d020-b25549742bafreVir', '66---aec8398c-ab92-6ec0-8b8e-987b0d378687reVir', '67---cd8e014c-d400-cbea-5741-6a603a953324reVir', '68---f15b21a9-a74b-4c79-b789-c6f0b31db3fereVir', '69---1dfdded0-3167-91a1-0999-2afaa2ce772ereVir', '70---14d9d312-d17f-7c3c-3e18-5f5e4b0b3590reVir', '71---670ce479-380a-e133-aadb-03bd5f9116dbreVir', '72---b5ce0c6d-a1f1-b68f-a011-f12ef99d113breVir', '73---e31a08cb-3d97-79c5-9997-0fdd4331893dreVir', '74---6967ff30-3271-4b8b-42c8-2944c599eab5reVir', '75---83f3eb59-79e2-1dfa-66ae-eaf1e97973c0reVir', '76---05f93b73-0e18-2e7e-f4e9-f2eda9d315dbreVir', '77---d11d9b2d-97f6-4152-dbc7-d98b4239db26reVir', '78---9670754d-45e9-e696-4f80-ba360e3fc45areVir', '79---9ecea9bc-e490-629d-7144-472c0100525areVir', '80---9e255764-3b52-4be9-40a3-f6747f666c83reVir', '81---f78aa415-2914-afe9-477f-0ab3528eebf2reVir', '82---b8722078-ffe6-4f5e-39d6-30ed9177e3a4reVir', '83---14aac023-8d24-76b5-a901-52c0b42e67e0reVir', '84---64f9af7e-da2d-9f33-a267-4d6a3687f541reVir', '85---6c944ba2-7152-d93b-9de3-2ddef460082creVir', '86---ea27e6e7-0889-0762-061d-b3824b755252reVir', '87---887961f0-6cce-7880-b230-eaa5b3dd32bcreVir', '88---8dd3355d-fb20-32eb-0a04-5142b0c46dcbreVir', '89---f062633d-1faf-459c-e397-4f42532b6deereVir', '90---a87d53f7-7a2e-2080-29c5-13b996982b06reVir', '91---a00ac7a5-bd7e-626a-8645-f61867c4ab87reVir', '92---97d5277f-4a37-13ad-7a1b-69e0ff2c351dreVir', '93---2ddae904-a058-99e1-e647-28bcd6d5ac06reVir', '94---658134b6-e4b3-5a99-daa3-36f143d31da6reVir', '95---4aa3e5fe-e2d8-be73-27bf-fd699704aa65reVir', '96---72945737-21e6-c005-66e8-5d425131be7dreVir', '97---29cfaa7f-163d-9c47-8a00-aa1c3ced9f51reVir', '98---4f45053a-3427-8d73-2ab3-12ef60f448e8reVir', '99---b870f0ba-868a-15c3-de2c-3fbdd4dc2a06reVir'] function rowRenderer({index, isScrolling, isVisible, key, parent, style}:any) { const content = list[index] return ( <div key={key} style={style}> {content} </div> ); } function onRowsRendered({startIndex}:any) { setState({ ...state, activeIndex: parseInt(String(startIndex / 10)) }) } function renderCityIndex() { return ( ['A00', 'B10', 'C20', 'D30', 'F40', 'G50', 'H60', 'J70', 'L80', 'M90'].map((item, index) => { return <li className={'cityIndexItem'} key={item} onClick={() => ListRef.current.scrollToRow(index * 10)} > <span className={state.activeIndex === index ? 'index-active' : ''}>{item}</span> </li> }) ) } return ( <div className='cityListClass'> <AutoSizer> {({height, width}) => ( <List ref={ListRef} width={width} height={height} rowCount={list.length} rowHeight={50} rowRenderer={rowRenderer} onRowsRendered={onRowsRendered} scrollToAlignment='start' /> )} </AutoSizer> <ul className="city-index">{renderCityIndex()}</ul> </div> ) } export default App
4、App.css
ul, li {
margin: 0;
padding: 0;
list-style: none;
}
.cityListClass {
height: 100vh;
}
.city-index {
position: fixed;
top: 10vh;
right: 3vh;
height: 66vh;
background-color: skyblue;
display: flex;
flex-direction: column;
align-items: center;
}
.cityIndexItem {
padding: 6px;
}
.index-active {
background-color: #fff;
}
注:
仅提供示例,根据实际需要修改业务需求!!!