我试图重现https://hexed.it/
显示的效果将鼠标悬停在其中一个列表上时,另一个列表中的相应字节也会突出显示。我想一个面板,里面的每个列表都有一个当前悬停字节的状态,但似乎React想要重新渲染整个列表,或者每次都做一些奇怪的事情,导致更大的文件慢得难以忍受。
我看到很多"使用备忘录!使用useCallback钩子!"当我在寻找,我试过了……它还是很慢,我不知道为什么。似乎它只渲染更新后的HexByte,但对于大文件来说,它仍然是不可接受的慢。
沙箱:https://codesandbox.io/s/flamboyant-ellis-btfk5s
有人能帮我加快/平滑悬停吗?
我用这个答案解决了这个问题:使用react-window防止DOM元素在虚拟树组件中重新呈现
总之,我学到的东西:
- 如果组件中有useState,则
- memo不起作用
- 大型数据列表应该使用react-window 之类的库来呈现。
- 上面回答中提到的单元格渲染函数不能是父组件的一部分
作为一个例子,新的hexpel类看起来像这样
import Box from '@mui/material/Box'; import { memo } from 'react'; import { FixedSizeGrid as Grid, areEqual } from 'react-window'; const HexByte = memo(function HexByte(props) { const onMouseEnter = () => { props.onHover(props.index); //setInside(true); } const onMouseLeave = () => { //setInside(false); } const onClick = () => { //setClicked(true); } return ( <span style={{ display: 'inline-block', padding: '5px', backgroundColor: props.hoverIndex == props.index ? '#777' : 'transparent', color: 'darkblue' }} onClick={onClick} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave} > {props.byte} </span> ) }, (prevProps, nextProps) => nextProps.hoverIndex != nextProps.index); const Cell = memo(function({ data, columnIndex, rowIndex, style }) { return ( <div style={style}> <HexByte byte={data.hex[rowIndex][columnIndex]} onHover={data.onHover} hoverIndex={data.hoverIndex} index={`${rowIndex}${columnIndex}`} /> </div> ) }, areEqual); const HexPanel = (props) => { return ( <Box sx={{ fontFamily: 'Source Code Pro', display: 'flex', flexDirection: 'column', }} > <Grid columnCount={16} columnWidth={30} height={900} itemData={props} rowCount={props.hex.length} rowHeight={35} width={500} > {Cell} </Grid> </Box> ) } export default HexPanel;