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

模态框内组件重复渲染两次的原因及修复方案咨询

问题分析与解决方案

为什么会出现两次渲染/API调用?

主要有两个核心原因:

  1. React 18 严格模式(Strict Mode)的刻意重复渲染
    在开发环境下,React 18的Strict Mode会对组件进行两次挂载/渲染(生产环境不会有这个行为),目的是帮你检测组件中可能存在的副作用问题。你的UsersFormPermissionsGroupPermissions组件里的useEffect没有依赖数组,所以每次渲染都会执行,加上Strict Mode的重复渲染,就触发了两次API调用。

  2. useEffect缺少依赖数组
    你的useEffect没有指定依赖项,这意味着它会在组件的每次渲染完成后都执行。哪怕没有Strict Mode,只要组件因为props/state变化重新渲染,这个useEffect都会再次触发API请求,这本身就是不符合预期的写法。

另外,父组件的条件渲染写法虽然不会直接导致两次渲染,但可以做些优化,避免不必要的组件销毁重建。


修复步骤

1. 给useEffect添加正确的依赖数组

修改UsersFormPermissionsGroupPermissions里的useEffect,把它依赖的变量idGroupCompany和dispatch加入依赖数组,这样只有当这些变量变化时,才会重新触发API请求:

useEffect(() => { 
  console.log('fetching permissions') 
  dispatch(groupPermissionsActions.getPermissionsGroupById(idGroupCompany))
}, [idGroupCompany, dispatch]) // 这里添加依赖项

如果dispatch是从Redux的useDispatch获取的,它本身是稳定的,可以安全加入依赖数组。

2. 优化组件传递,避免不必要的重渲染

把UsersFormPermissionsGroupPermissions用React.memo包裹,这样当它的props没有变化时,不会重复渲染:

import { memo } from 'react';

const UsersFormPermissionsGroupPermissions = memo(() => {
  // 你的组件代码
})

同时,父组件传递FormComponent的时候,不要在渲染时创建新的组件引用(不过你现在是直接传组件,没问题,但如果是传渲染函数的话要注意)。

3. (可选)理解Strict Mode的行为

如果你只是在开发环境看到两次调用,生产环境不会有这个问题,这是React的正常检测机制。如果想暂时关闭Strict Mode,可以在index.js里去掉<StrictMode>标签,但不建议这么做,因为它能帮你提前发现潜在的bug。

4. 优化父组件的条件渲染写法

父组件里的条件渲染可以简化,不需要写三元表达式的空片段,直接写成:

{openFullScreenModal && (
  <ModalFullScreen 
    FormComponent={UsersFormPermissionsGroupPermissions} 
    title="Permissões do grupo" 
    onCloseModal={setOpenFullScreenModal} 
    open={openFullScreenModal} 
  />
)}

这样代码更简洁,而且逻辑上和原来一致。


验证修复效果

修改后,在开发环境下,Strict Mode仍然会触发两次组件渲染,但因为useEffect有了依赖数组,只有当idGroupCompany变化时才会执行API请求;如果idGroupCompany没有变化,第二次渲染时useEffect不会重复执行,从而避免了两次API调用。生产环境下则只会执行一次。

内容的提问来源于stack exchange,提问作者匿名用户

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 09:12:49