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

React严格模式下UseState初始加载触发过多重渲染问题求解

问题根因

核心问题是在组件渲染流程的map遍历中直接调用了状态更新函数setstatus:React组件渲染过程中一旦触发状态更新,会立即触发组件重渲染,重渲染又会再次执行map逻辑、再次调用setstatus,形成无限渲染循环,所以会触发过多重渲染报错,和严格模式、useEffect的使用没有关系,属于写法不符合React的渲染规则。

可行解决方案

方案1:抽离子组件+用props做状态初始值(最适配你的场景)

你的工位初始状态本身就存在buildingProps.workStations的station.status字段,不需要在渲染时重复赋值给状态,直接把单条工位行抽成独立子组件,将station.status作为子组件状态的初始值即可:

// 抽离独立的单工位行组件
const WorkStationRow = ({ station, buildingProps }) => {
  // 直接用props传入的工位状态作为初始值,不需要渲染时更新
  const [status, setStatus] = useState(station.status);

  const handleReserve = () => {
    const isReserved = reserveStation(station, buildingProps.setReservationInfo);
    buildingProps.setShow(isReserved); 
    isReserved ? setStatus(statusValue.reserved) : setStatus(statusValue.inUse);
  }

  return (
    <TableRow key={station.stationName}>
      <TableCell className={`stationStatus-${station.id}`} w="150px">
        {checkStation(status)}
      </TableCell>
      {/* 其他工位信息渲染逻辑 */}
      <TableCell className="reservationButton">
        <Button variantColor="teal" onClick={handleReserve}>
          预约
        </Button>
      </TableCell>
    </TableRow>
  )
}

// 父组件只负责遍历渲染子组件,不要在渲染逻辑中调用状态更新
return (
  <Card w="80%" ml="10%" mt={buildingProps.marginTop} boxShadow="0">
    <CardTitle>{buildingProps.buildingName}</CardTitle>
    <Table>
      <TableHead>
        {/* 表头渲染逻辑 */}
      </TableHead>
      <TableBody>
        {buildingProps.workStations.map((station: Workstation) => (
          <WorkStationRow 
            key={station.stationName} 
            station={station} 
            buildingProps={buildingProps}
          />
        ))}
      </TableBody>
    </Table>
  </Card>
)

方案2:加useEffect同步父级状态变更(可选)

如果后续父级传入的station.status会发生变化,需要同步到子组件的状态,只需要在子组件中加依赖为station.status的useEffect即可,不会触发多余渲染:

useEffect(() => {
  setStatus(station.status);
}, [station.status]); // 只有station.status实际变化时才会执行更新

方案3:状态提升到父级统一管理(适合多场景共享工位状态的情况)

如果其他组件也需要用到工位状态,直接把所有工位的状态存在父级统一管理,子组件触发更新时直接修改父级的状态数组即可,不需要每个子组件单独维护状态:

// 父组件中定义工位状态和更新方法
const [workStations, setWorkStations] = useState(initialWorkStations);

const updateStationStatus = (stationId, newStatus) => {
  setWorkStations(prev => prev.map(item => 
    item.id === stationId ? {...item, status: newStatus} : item
  ))
}

注意事项

  • React严格模式只会在开发环境下重复执行两次渲染、两次useEffect来检测非法副作用,不会导致无限渲染,你的问题和严格模式无关
  • 永远不要在组件的顶层渲染逻辑(包括map遍历、return之前的同步代码)中调用setState,所有状态更新要么放在用户事件回调里,要么放在useEffect的副作用回调里

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 00:27:01