fix(web): 修复点击设置后白屏(React hooks 顺序违规)
子模态框 ESC 处理的 useEffect 被放在 if(loading)/if(!config) 条件 return 之后,导致首次渲染(loading=true)时不执行该 hook,config 加载后重新渲染才执行 → hooks 数量不一致 → React error #310 白屏崩溃。 修复:将 useEffect 移到所有条件 return 之前,与其他 hooks 放在一起。
This commit is contained in:
parent
951e31aca4
commit
003eab4f21
@ -200,6 +200,23 @@ export function ConfigPage({ onClose, onSaveConnection, initialTab }: ConfigPage
|
|||||||
return () => document.removeEventListener('keydown', h)
|
return () => document.removeEventListener('keydown', h)
|
||||||
}, [handleClose])
|
}, [handleClose])
|
||||||
|
|
||||||
|
// 子模态框打开时,ESC 键仅关闭子模态框(阻止冒泡到 ConfigPage 全局 ESC,避免关闭整个配置页)
|
||||||
|
// 必须放在所有条件 return 之前,否则 loading 首次渲染时不执行此 hook,
|
||||||
|
// config 加载后重新渲染才执行 → hooks 数量不一致 → React 崩溃
|
||||||
|
useEffect(() => {
|
||||||
|
if (!editingExpert && !editingSubagent) return
|
||||||
|
const handler = (e: KeyboardEvent) => {
|
||||||
|
if (e.key === 'Escape') {
|
||||||
|
e.stopPropagation()
|
||||||
|
e.preventDefault()
|
||||||
|
setEditingExpert(null)
|
||||||
|
setEditingSubagent(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
window.addEventListener('keydown', handler, true)
|
||||||
|
return () => window.removeEventListener('keydown', handler, true)
|
||||||
|
}, [editingExpert, editingSubagent])
|
||||||
|
|
||||||
const update = useCallback(<K extends keyof AppConfig>(key: K, value: AppConfig[K]) => {
|
const update = useCallback(<K extends keyof AppConfig>(key: K, value: AppConfig[K]) => {
|
||||||
setConfig(prev => prev ? { ...prev, [key]: value } : prev)
|
setConfig(prev => prev ? { ...prev, [key]: value } : prev)
|
||||||
setDirty(true)
|
setDirty(true)
|
||||||
@ -904,21 +921,6 @@ export function ConfigPage({ onClose, onSaveConnection, initialTab }: ConfigPage
|
|||||||
const toolEmptyHint = toolListLoading ? '加载中...' : '未发现任何工具'
|
const toolEmptyHint = toolListLoading ? '加载中...' : '未发现任何工具'
|
||||||
const subagentEmptyHint = subagentListLoading ? '加载中...' : '未发现任何子代理'
|
const subagentEmptyHint = subagentListLoading ? '加载中...' : '未发现任何子代理'
|
||||||
|
|
||||||
// 子模态框打开时,ESC 键仅关闭子模态框(阻止冒泡到 ConfigPage 全局 ESC,避免关闭整个配置页)
|
|
||||||
useEffect(() => {
|
|
||||||
if (!editingExpert && !editingSubagent) return
|
|
||||||
const handler = (e: KeyboardEvent) => {
|
|
||||||
if (e.key === 'Escape') {
|
|
||||||
e.stopPropagation()
|
|
||||||
e.preventDefault()
|
|
||||||
setEditingExpert(null)
|
|
||||||
setEditingSubagent(null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
window.addEventListener('keydown', handler, true)
|
|
||||||
return () => window.removeEventListener('keydown', handler, true)
|
|
||||||
}, [editingExpert, editingSubagent])
|
|
||||||
|
|
||||||
const renderExpertModal = () => {
|
const renderExpertModal = () => {
|
||||||
if (!editingExpert) return null
|
if (!editingExpert) return null
|
||||||
const isEdit = editingExpert.mode === 'edit'
|
const isEdit = editingExpert.mode === 'edit'
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user