mirror of
https://github.com/stablyai/orca.git
synced 2026-10-20 00:03:45 +00:00
fix: stop mutating refs during render for React Doctor
Replace render-time ref writes in TasksPane sticky auto-expand and active project skill runtime identity caching with setState-during-render so static analysis can pass without changing behavior.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useRef } from 'react'
|
||||
import { useState } from 'react'
|
||||
import { Github, Gitlab } from 'lucide-react'
|
||||
import type { GlobalSettings, TaskProvider } from '../../../../shared/types'
|
||||
import {
|
||||
@@ -103,17 +103,17 @@ export function TasksPane({ settings, updateSettings }: TasksPaneProps): React.J
|
||||
// Warn only about started-then-stalled setup; untouched providers are the default.
|
||||
const stalledVisible = getStalledVisibleTaskProviders(TASK_PROVIDERS, readinessByProvider)
|
||||
// Sticky across rechecks so expanded Linear install terminals are not unmounted.
|
||||
const previousAutoExpandedRef = useRef<TaskProvider | null>(null)
|
||||
// Claim during render (not an effect): a layout effect elsewhere can force a
|
||||
// sync re-render before passive effects flush and collapse the open card.
|
||||
// useState (not a ref write) keeps render pure for React Doctor.
|
||||
const [previousAutoExpanded, setPreviousAutoExpanded] = useState<TaskProvider | null>(null)
|
||||
const autoExpandedProvider = resolveStickyAutoExpandedTaskProvider({
|
||||
providers: TASK_PROVIDERS,
|
||||
readinessByProvider,
|
||||
previousAutoExpanded: previousAutoExpandedRef.current
|
||||
previousAutoExpanded
|
||||
})
|
||||
// Claim during render, not in an effect: a layout effect elsewhere can force a
|
||||
// sync re-render before passive effects flush, and that render would see an
|
||||
// unclaimed slot and collapse the open card.
|
||||
if (autoExpandedProvider !== null && previousAutoExpandedRef.current === null) {
|
||||
previousAutoExpandedRef.current = autoExpandedProvider
|
||||
if (autoExpandedProvider !== null && previousAutoExpanded === null) {
|
||||
setPreviousAutoExpanded(autoExpandedProvider)
|
||||
}
|
||||
|
||||
const toggleProvider = (provider: TaskProvider): void => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useMemo, useRef } from 'react'
|
||||
import { useMemo, useState } from 'react'
|
||||
import { useShallow } from 'zustand/react/shallow'
|
||||
import type { ProjectExecutionRuntimeResolution } from '../../../shared/project-execution-runtime'
|
||||
import type { SkillDiscoveryTarget } from '../../../shared/skills'
|
||||
@@ -86,14 +86,15 @@ export function useActiveProjectSkillRuntime(): ActiveProjectSkillRuntime {
|
||||
}
|
||||
}, [currentPlatform, runtimeState, windowsCapabilities])
|
||||
|
||||
const stableRef = useRef(resolved)
|
||||
if (
|
||||
activeProjectSkillRuntimeIdentity(stableRef.current) !==
|
||||
activeProjectSkillRuntimeIdentity(resolved)
|
||||
) {
|
||||
stableRef.current = resolved
|
||||
// Content-equal runtimes keep one reference so effect keys do not thrash.
|
||||
// Adjust during render (not a ref write) when serialized identity changes.
|
||||
const [stable, setStable] = useState(resolved)
|
||||
const stableIdentity = activeProjectSkillRuntimeIdentity(stable)
|
||||
const resolvedIdentity = activeProjectSkillRuntimeIdentity(resolved)
|
||||
if (stableIdentity !== resolvedIdentity) {
|
||||
setStable(resolved)
|
||||
}
|
||||
return stableRef.current
|
||||
return stableIdentity === resolvedIdentity ? stable : resolved
|
||||
}
|
||||
|
||||
function getCurrentPlatform(): NodeJS.Platform {
|
||||
|
||||
Reference in New Issue
Block a user