React:阻止列表在道具改变时重新渲染所有元素



我试图重现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;