You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Material UI Popover如何不使用Hook实现弹出,解决Hook渲染数量不一致报错

方案1:CSS hover实现(最推荐,性能最优)

你的交互仅为鼠标悬停触发展示,无需JS管理状态,直接用CSS控制显隐即可完全规避Hook相关问题:

import React from 'react';
import Box from '@material-ui/core/Box';
import ImageCell from 'App/components/DatabaseTable/Utils/ImageCell';

const Image = ({ defaultValueRow, valueRow }) => {
  const id = `popover-${defaultValueRow[valueRow]}`;
  const imgSrc = valueRow[defaultValueRow];

  return (
    <Box 
      sx={{
        position: 'relative',
        '&:hover .hover-popover': {
          display: 'block'
        }
      }} 
      aria-haspopup="true" 
      aria-owns={id}
    >
      <Box>
        <ImageCell src={imgSrc} />
      </Box>
      <Box
        id={id}
        className="hover-popover"
        sx={{
          pointerEvents: 'none',
          position: 'absolute',
          padding: '8px',
          bottom: '100%',
          left: '50%',
          transform: 'translateX(-50%)',
          display: 'none',
          zIndex: 9999,
          bgcolor: 'background.paper',
          borderRadius: 1,
          boxShadow: 3
        }}
      >
        <ImageCell
          style={{ maxWidth: '125rem', maxHeight: '15rem' }}
          src={imgSrc}
        />
      </Box>
    </Box>
  );
};

export default Image;

方案2:重写为类组件(兼容MUI Popover原生能力)

如果需要保留MUI Popover的所有原生特性(如自动边界检测、定位、层级处理等),可以将组件改写为类组件,用类内部状态管理anchorEl,完全不涉及Hook调用:

import React, { Component } from 'react';
import Box from '@material-ui/core/Box';
import Popover from '@material-ui/core/Popover';
import ImageCell from 'App/components/DatabaseTable/Utils/ImageCell';

class Image extends Component {
  state = {
    anchorEl: null
  };

  handlePopoverOpen = (event) => {
    this.setState({ anchorEl: event.currentTarget });
  };

  handlePopoverClose = () => {
    this.setState({ anchorEl: null });
  };

  render() {
    const { defaultValueRow, valueRow } = this.props;
    const { anchorEl } = this.state;
    const id = `popover-${defaultValueRow[valueRow]}`;
    const imgSrc = valueRow[defaultValueRow];

    return (
      <>
        <Box
          aria-haspopup="true"
          aria-owns={anchorEl ? id : undefined}
          onMouseEnter={this.handlePopoverOpen}
          onMouseLeave={this.handlePopoverClose}
        >
          <ImageCell src={imgSrc} />
        </Box>
        <Popover
          id={id}
          style={{ pointerEvents: 'none' }}
          PaperProps={{
            style: { padding: '8px' },
          }}
          open={Boolean(anchorEl)}
          anchorEl={anchorEl}
          anchorOrigin={{
            vertical: 'top',
            horizontal: 'center',
          }}
          transformOrigin={{
            vertical: 'bottom',
            horizontal: 'center',
          }}
        >
          <ImageCell
            style={{ maxWidth: '125rem', maxHeight: '15rem' }}
            src={imgSrc}
          />
        </Popover>
      </>
    );
  }
}

export default Image;

补充说明

你遇到的Rendered more hooks than during the previous render报错本质并非useState本身导致,而是该组件的Hook调用次数/顺序在重渲染前后不一致,通常是由上层条件渲染、或组件内部Hook调用前存在提前return逻辑导致。如果后续需要使用Hook,可优先排查上述问题。

内容的提问来源于stack exchange,提问作者Sonhja

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 22:24:05