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

如何基于Apollo Hook数据条件渲染Material-UI Dialog并避免重渲染异常

问题根源

  1. 无限重渲染的核心原因是你直接在组件渲染主逻辑中调用setIsDialogOpen:setState会触发组件重渲染,只要checker为true就会再次执行setState,进入死循环。
  2. Array.some()的调用语法错误,你当前的写法不会正确执行匹配逻辑,正确写法需要传入回调函数。
  3. 直接用checker作为open属性值时,checker仅和接口返回数据绑定,和本地关闭状态无关联,自然点击关闭按钮不会生效。
  4. 第二版条件渲染代码存在JSX语法错误,return中直接写{checker && ...}不符合JSX语法规范。

可行解决方案

使用useEffect监听Apollo查询返回的data和目标id变化,仅在依赖项更新时判断是否需要自动打开对话框,避免每次渲染都触发状态更新。

const DialogComponent = () => {
    const {data, loading, error} = useQuery(GET_QUERY_DATA)
    const [isDialogOpen, setIsDialogOpen] = useState(false);
    // 修正some方法的回调写法,加可选链避免空值报错
    const checker = data?.getData?.some(item => item.id === id) ?? false;

    const closeDialog = () => {
      setIsDialogOpen(false)
    }
 
    // 仅当data、id、加载状态变化时,判断是否要自动打开弹窗
    useEffect(() => {
      // 等接口加载完成后再执行判断,避免空值误判
      if(!loading && checker) {
        setIsDialogOpen(true)
      }
    }, [data, id, loading, checker])

    // 可自定义加载、错误状态的兜底展示
    if(loading) return <div>加载中</div>
    if(error) return <div>数据加载失败</div>

   return(
        <Dialog
          open={isDialogOpen}
          close={closeDialog}>
                   {/* 对话框内容代码 */}
            <DialogActions>
              <Button onClick={closeDialog}> Close </Button>
            </DialogActions>
          </Dialog>
   )
}

逻辑说明

  • useEffect的依赖项仅包含和弹窗自动打开逻辑相关的变量,只有这些变量变化时才会执行判断逻辑,不会触发无限重渲染
  • 本地状态isDialogOpen独立控制弹窗的开关,接口返回的checker仅负责自动打开的触发逻辑,关闭操作完全由本地状态控制,互不干扰
  • 提前处理了loading和error状态,避免接口返回前的空值判断错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 00:06:01