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

React Vite项目组件渲染时setState警告的解决求助

解决React中“Cannot update a component while rendering a different component”警告

错误根源分析

  1. 违反React Hooks规则:在data.map循环内部声明useState,Hooks必须在组件顶层调用,不能嵌套在循环、条件判断或子函数中。
  2. 渲染期间更新状态:在AccordionItemState的渲染回调中直接调用setClassName,此时React正在渲染Context.Consumer(AccordionItemState内部的上下文消费者),却触发了Value组件的状态更新,导致渲染不一致警告。
  3. 缓存残留问题:删除代码后仍有警告,大概率是浏览器缓存或Vite热更新残留导致旧代码未完全替换。

解决方案

1. 移除无效状态管理,利用组件内置状态

直接使用react-accessible-accordion提供的expanded状态动态生成类名,无需额外维护className状态。

2. 修复Hooks使用方式

确保所有Hooks都在组件顶层调用,避免嵌套在循环或子函数中。

3. 清除缓存并重启服务

  • 按Ctrl+Shift+R强制刷新浏览器清除缓存
  • 停止Vite开发服务器后重新启动(执行npm run dev/yarn dev)

完整修正代码

import React from 'react';
import {
  Accordion,
  AccordionItem,
  AccordionItemHeading,
  AccordionItemButton,
  AccordionItemPanel,
  AccordionItemState
} from 'react-accessible-accordion';

import { MdOutlineArrowDropDown } from 'react-icons/md';
import data from '../../utils/accordion';
import './value.css';

const Value = () => {
  return (
    <section className="v-wrapper">
      <div className="padding innerWidth flexCenter v-container">
        {/* Left Side */}
        <div className="v-left">
          <div className="image-container">
            <img src="./value.png" alt="Value illustration" />
          </div>
        </div>
        <div className="flexColStart v-right">
          <span className="orangeText">Title</span>
          <span className="secondaryText">Why </span>
          <span className="secondaryText"> description</span>

          <Accordion
            className="accordion"
            allowMultipleExpanded={false}
            preExpanded={[0]}
          >
            {data.map((item, i) => (
              <AccordionItem 
                key={i} 
                uuid={i}
                className={`accordionItem`}
              >
                <AccordionItemHeading>
                  <AccordionItemButton className="flexCenter accordionButton">
                    <AccordionItemState>
                      {({ expanded }) => (
                        <>
                          <div className="flexCenter icon">{item.icon}</div>
                          <span className="secondaryText">{item.heading}</span>
                          <div className={`flexCenter icon ${expanded ? 'expanded' : 'collapsed'}`}>
                            <MdOutlineArrowDropDown size={20} />
                          </div>
                        </>
                      )}
                    </AccordionItemState>
                  </AccordionItemButton>
                </AccordionItemHeading>
                <AccordionItemPanel>
                  <p className="secondaryText">{item.detail}</p>
                </AccordionItemPanel>
              </AccordionItem>
            ))}
          </Accordion>
        </div>
      </div>
    </section>
  );
};

export default Value;

代码说明

  • 移除了循环内的useState声明,不再违反Hooks规则
  • 直接通过AccordionItemState提供的expanded状态动态控制类名,无需额外状态更新
  • 避免了在渲染回调中触发状态更新的操作,彻底消除警告

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 07:29:54