From 5c73321ce6b3c3b49af8b8e9e9016c4a7f243b9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E8=88=AA=E5=AE=87?= <3364451258@qq.com> Date: Fri, 29 May 2026 17:02:55 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20ESLint=20set-state-?= =?UTF-8?q?in-effect=20=E9=94=99=E8=AF=AF=20=E2=80=94=20useEffect=20?= =?UTF-8?q?=E5=8A=A0=20prevOpen=20=E5=AE=88=E5=8D=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.7 --- README.md | 6 ++++++ src/components/dialogs/AnalyzeDialog.tsx | 6 ++++-- src/components/dialogs/ProfileDialog.tsx | 6 ++++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c07eac7..f5a23d9 100644 --- a/README.md +++ b/README.md @@ -172,6 +172,7 @@ patheditor profile apply "Python开发" ## 功能 ### 路径管理 + - 查看和编辑 **系统 PATH**(HKLM)和 **用户 PATH**(HKCU) - 新建、编辑、删除、上移、下移路径条目 - 多选批量删除 @@ -180,26 +181,31 @@ patheditor profile apply "Python开发" - 文件夹拖拽添加 ### 路径验证 + - **红色**标记:路径在文件系统中不存在 - **橙色**标记:路径在列表中重复出现 - 环境变量路径(含 `%VAR%`)悬浮展开预览 ### 撤销/重做 + - 支持 9 种操作类型,最多 50 步历史 - 新增、删除、编辑、移动、清理、清空、导入均可撤销 ### 导入/导出 + - **JSON**:结构化导出,含版本和时间戳 - **CSV**:UTF-8 BOM 编码,兼容 Excel - **TXT**:纯文本,每行一个路径 ### 安全 + - 保存前自动备份注册表到 `%APPDATA%/PathEditor/backups/` - PATH 长度检查(Windows 单变量上限 32767 字符) - 非管理员自动进入**只读模式** - 保存中途失败精确提示哪个注册表 hive 出错 ### 界面 + - 深色模式 / 浅色模式 - 中文 / English 界面切换 - 全局键盘快捷键 diff --git a/src/components/dialogs/AnalyzeDialog.tsx b/src/components/dialogs/AnalyzeDialog.tsx index 186128d..e6cf400 100644 --- a/src/components/dialogs/AnalyzeDialog.tsx +++ b/src/components/dialogs/AnalyzeDialog.tsx @@ -1,4 +1,4 @@ -import { useState, useEffect, useMemo } from 'react'; +import { useState, useEffect, useMemo, useRef } from 'react'; import { invoke } from '@tauri-apps/api/core'; import { useTranslation } from 'react-i18next'; import { Modal } from '@/components/ui/Modal'; @@ -35,8 +35,10 @@ export function AnalyzeDialog({ open, onClose }: Props) { const [toolGroups, setToolGroups] = useState([]); const [searchQuery, setSearchQuery] = useState(''); + const prevOpen = useRef(false); useEffect(() => { - if (!open) return; + if (!open || prevOpen.current) return; + prevOpen.current = open; setLoading(true); const paths = getEnabledPaths(); Promise.all([ diff --git a/src/components/dialogs/ProfileDialog.tsx b/src/components/dialogs/ProfileDialog.tsx index 2a0abc6..59be6cb 100644 --- a/src/components/dialogs/ProfileDialog.tsx +++ b/src/components/dialogs/ProfileDialog.tsx @@ -1,4 +1,4 @@ -import { useState, useEffect, useCallback } from 'react'; +import { useState, useEffect, useCallback, useRef } from 'react'; import { invoke } from '@tauri-apps/api/core'; import { useTranslation } from 'react-i18next'; import { Modal } from '@/components/ui/Modal'; @@ -39,8 +39,10 @@ export function ProfileDialog({ open, onClose }: Props) { setProfiles(list); }, []); + const prevOpen = useRef(false); useEffect(() => { - if (open) refreshProfiles(); + if (open && !prevOpen.current) refreshProfiles(); + prevOpen.current = open; }, [open, refreshProfiles]); const handleSave = async () => {