【问题标题】:Preventing unnecessary re-renders of table rows / children in React防止在 React 中不必要地重新渲染表行/子项
【发布时间】:2021-12-23 21:29:26
【问题描述】:

假设有一个表格需要保持某种状态,例如,知道最后一个悬停在上面的元素。为此,我们需要一个子元素上的onMouseOver 事件,如下所示:

<tr onMouseOver={handleMouseOver}></tr>

然后包含表格的组件将在setState({lastHovered: e.target}) 之后重新渲染所有子项(类似这些行)

如果悬停的目标是仅更改一行(假设显示/隐藏某些内容而不使用 CSS),是否有办法将此状态保持在高于该行的级别,并且仅在 @987654324 中呈现更改受悬停影响的@s?

例如,假设鼠标悬停在桌子内或桌子外会有延迟。悬停时,子级应显示工具提示,但前提是直接悬停在上方。表/父级需要维护一些状态来跟踪这一点但有没有办法不必重新渲染整个子级列表?

【问题讨论】:

    标签: javascript reactjs user-interface hover state


    【解决方案1】:

    对于功能组件

    将所有tr 元素包装在React.memo (read) 中,以仅侦听对其内部属性的更改。此外,将onMouseOver 事件放在表本身而不是每个子直接元素上,然后检查哪个子元素处于“焦点”中(即event.target)。

    内表组件:

    const [lastHovered, setLastHovered] = useState(null);
    const [trProps, setTrProps] = useState(null);
    
    return (
      <table onMouseOver={event => setLastHovered(event.target) /* Also check if 'TR' type */ }> 
        <TableRows someData={trProps} />
      </table>
    )
    

    表格行组件:

    const TableRows = React.memo( ({someData}) => /* Triggers update only if 'someData' changes */
          <> { someData.map( data => <tr>{data}</tr> ) } </>
        )
    

    注意:以上代码未经测试;写来演示一个可能的解决方案。

    对于类组件

    如果您使用类组件,则创建自定义 TableRow 元素并添加 shouldComponentUpdate() (read) 以控制重新呈现,或者改用 PureComponents (read)。

    【讨论】:

    • 谢谢,这看起来正是我所需要的。有点扭曲......假设我需要在一段时间后显示该工具提示。悬停更改的执行方式对存储状态(表)的位置没有影响,我理解正确吗?
    • 如果表格行的视觉效果由 CSS 处理,则悬停更改不应影响状态的存储位置。但是,如果表格行组件依赖于JSmouseOver事件来触发悬停效果,那我们就不得不重新考虑解决方案了。不过,PureComponents 方法会是更好的选择。
    • 那你介意看看我之前的问题吗? stackoverflow.com/questions/70446284/… 记忆化仍然是一个值得探索的好主意
    • @McDerp 我针对该问题发布了一个可能的解决方案。
    猜你喜欢
    • 2018-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多