mirror of
https://github.com/LHY0125/PathEditor.git
synced 2026-06-28 17:25:54 +08:00
fix: 修复 ESLint set-state-in-effect 错误 — useEffect 加 prevOpen 守卫
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -172,6 +172,7 @@ patheditor profile apply "Python开发"
|
|||||||
## 功能
|
## 功能
|
||||||
|
|
||||||
### 路径管理
|
### 路径管理
|
||||||
|
|
||||||
- 查看和编辑 **系统 PATH**(HKLM)和 **用户 PATH**(HKCU)
|
- 查看和编辑 **系统 PATH**(HKLM)和 **用户 PATH**(HKCU)
|
||||||
- 新建、编辑、删除、上移、下移路径条目
|
- 新建、编辑、删除、上移、下移路径条目
|
||||||
- 多选批量删除
|
- 多选批量删除
|
||||||
@@ -180,26 +181,31 @@ patheditor profile apply "Python开发"
|
|||||||
- 文件夹拖拽添加
|
- 文件夹拖拽添加
|
||||||
|
|
||||||
### 路径验证
|
### 路径验证
|
||||||
|
|
||||||
- **红色**标记:路径在文件系统中不存在
|
- **红色**标记:路径在文件系统中不存在
|
||||||
- **橙色**标记:路径在列表中重复出现
|
- **橙色**标记:路径在列表中重复出现
|
||||||
- 环境变量路径(含 `%VAR%`)悬浮展开预览
|
- 环境变量路径(含 `%VAR%`)悬浮展开预览
|
||||||
|
|
||||||
### 撤销/重做
|
### 撤销/重做
|
||||||
|
|
||||||
- 支持 9 种操作类型,最多 50 步历史
|
- 支持 9 种操作类型,最多 50 步历史
|
||||||
- 新增、删除、编辑、移动、清理、清空、导入均可撤销
|
- 新增、删除、编辑、移动、清理、清空、导入均可撤销
|
||||||
|
|
||||||
### 导入/导出
|
### 导入/导出
|
||||||
|
|
||||||
- **JSON**:结构化导出,含版本和时间戳
|
- **JSON**:结构化导出,含版本和时间戳
|
||||||
- **CSV**:UTF-8 BOM 编码,兼容 Excel
|
- **CSV**:UTF-8 BOM 编码,兼容 Excel
|
||||||
- **TXT**:纯文本,每行一个路径
|
- **TXT**:纯文本,每行一个路径
|
||||||
|
|
||||||
### 安全
|
### 安全
|
||||||
|
|
||||||
- 保存前自动备份注册表到 `%APPDATA%/PathEditor/backups/`
|
- 保存前自动备份注册表到 `%APPDATA%/PathEditor/backups/`
|
||||||
- PATH 长度检查(Windows 单变量上限 32767 字符)
|
- PATH 长度检查(Windows 单变量上限 32767 字符)
|
||||||
- 非管理员自动进入**只读模式**
|
- 非管理员自动进入**只读模式**
|
||||||
- 保存中途失败精确提示哪个注册表 hive 出错
|
- 保存中途失败精确提示哪个注册表 hive 出错
|
||||||
|
|
||||||
### 界面
|
### 界面
|
||||||
|
|
||||||
- 深色模式 / 浅色模式
|
- 深色模式 / 浅色模式
|
||||||
- 中文 / English 界面切换
|
- 中文 / English 界面切换
|
||||||
- 全局键盘快捷键
|
- 全局键盘快捷键
|
||||||
|
|||||||
@@ -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 { invoke } from '@tauri-apps/api/core';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Modal } from '@/components/ui/Modal';
|
import { Modal } from '@/components/ui/Modal';
|
||||||
@@ -35,8 +35,10 @@ export function AnalyzeDialog({ open, onClose }: Props) {
|
|||||||
const [toolGroups, setToolGroups] = useState<ToolGroup[]>([]);
|
const [toolGroups, setToolGroups] = useState<ToolGroup[]>([]);
|
||||||
const [searchQuery, setSearchQuery] = useState('');
|
const [searchQuery, setSearchQuery] = useState('');
|
||||||
|
|
||||||
|
const prevOpen = useRef(false);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!open) return;
|
if (!open || prevOpen.current) return;
|
||||||
|
prevOpen.current = open;
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const paths = getEnabledPaths();
|
const paths = getEnabledPaths();
|
||||||
Promise.all([
|
Promise.all([
|
||||||
|
|||||||
@@ -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 { invoke } from '@tauri-apps/api/core';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Modal } from '@/components/ui/Modal';
|
import { Modal } from '@/components/ui/Modal';
|
||||||
@@ -39,8 +39,10 @@ export function ProfileDialog({ open, onClose }: Props) {
|
|||||||
setProfiles(list);
|
setProfiles(list);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const prevOpen = useRef(false);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (open) refreshProfiles();
|
if (open && !prevOpen.current) refreshProfiles();
|
||||||
|
prevOpen.current = open;
|
||||||
}, [open, refreshProfiles]);
|
}, [open, refreshProfiles]);
|
||||||
|
|
||||||
const handleSave = async () => {
|
const handleSave = async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user