feat(ideContainer): 使用redux实时缓存画布的对应数据,引入防抖函数优化性能

production
钟良源 7 months ago
parent 5f39448f74
commit f48036f26a

@ -18,6 +18,9 @@ import {
ConnectionLineType ConnectionLineType
} from '@xyflow/react'; } from '@xyflow/react';
import '@xyflow/react/dist/style.css'; import '@xyflow/react/dist/style.css';
import { useSelector, useDispatch } from 'react-redux';
import { updateCanvasDataMap } from '@/store/ideContainer';
import { debounce } from 'lodash';
import { nodeTypeMap, nodeTypes, registerNodeType } from '@/components/FlowEditor/node'; import { nodeTypeMap, nodeTypes, registerNodeType } from '@/components/FlowEditor/node';
import SideBar from './sideBar/sideBar'; import SideBar from './sideBar/sideBar';
import { convertFlowData, revertFlowData } from '@/utils/convertFlowData'; import { convertFlowData, revertFlowData } from '@/utils/convertFlowData';
@ -55,6 +58,7 @@ const FlowEditorWithProvider: React.FC<{ initialData?: any }> = ({ initialData }
const FlowEditor: React.FC<{ initialData?: any }> = ({ initialData }) => { const FlowEditor: React.FC<{ initialData?: any }> = ({ initialData }) => {
const [nodes, setNodes] = useState<Node[]>([]); const [nodes, setNodes] = useState<Node[]>([]);
const [edges, setEdges] = useState<Edge[]>([]); const [edges, setEdges] = useState<Edge[]>([]);
const { canvasDataMap } = useSelector(state => state.ideContainer);
const reactFlowInstance = useReactFlow(); const reactFlowInstance = useReactFlow();
const reactFlowWrapper = useRef<HTMLDivElement>(null); const reactFlowWrapper = useRef<HTMLDivElement>(null);
const [menu, setMenu] = useState<{ const [menu, setMenu] = useState<{
@ -65,6 +69,7 @@ const FlowEditor: React.FC<{ initialData?: any }> = ({ initialData }) => {
position?: { x: number; y: number }; position?: { x: number; y: number };
} | null>(null); } | null>(null);
const store = useStoreApi(); const store = useStoreApi();
const dispatch = useDispatch();
// 添加编辑弹窗相关状态 // 添加编辑弹窗相关状态
const [editingNode, setEditingNode] = useState<Node | null>(null); const [editingNode, setEditingNode] = useState<Node | null>(null);
@ -77,6 +82,15 @@ const FlowEditor: React.FC<{ initialData?: any }> = ({ initialData }) => {
const { getGuidelines, clearGuidelines, AlignmentGuides } = useAlignmentGuidelines(); const { getGuidelines, clearGuidelines, AlignmentGuides } = useAlignmentGuidelines();
const updateCanvasDataMapDebounced = useRef(
debounce((dispatch, canvasDataMap, id, nodes, edges) => {
dispatch(updateCanvasDataMap({
...canvasDataMap,
[id]: { nodes, edges }
}));
}, 500)
).current;
// 获取handle类型 (api或data) // 获取handle类型 (api或data)
const getHandleType = (handleId: string, nodeParams: any) => { const getHandleType = (handleId: string, nodeParams: any) => {
// 检查是否为api类型的handle // 检查是否为api类型的handle
@ -310,17 +324,44 @@ const FlowEditor: React.FC<{ initialData?: any }> = ({ initialData }) => {
}, [clearGuidelines]); }, [clearGuidelines]);
useEffect(() => { useEffect(() => {
const { nodes: convertedNodes, edges: convertedEdges } = convertFlowData(initialData); if (canvasDataMap[initialData?.id]) {
// 为所有边添加类型- const { edges, nodes } = canvasDataMap[initialData?.id];
const initialEdges: Edge[] = convertedEdges.map(edge => ({ setNodes(nodes);
...edge, setEdges(edges);
type: 'custom' }
})); else {
// 首次进入
setNodes(convertedNodes); const { nodes: convertedNodes, edges: convertedEdges } = convertFlowData(initialData);
setEdges(initialEdges); // 为所有边添加类型-
const initialEdges: Edge[] = convertedEdges.map(edge => ({
...edge,
type: 'custom'
}));
setNodes(convertedNodes);
setEdges(initialEdges);
if (initialData?.id) {
dispatch(updateCanvasDataMap({
...canvasDataMap,
[initialData.id]: { convertedNodes, initialEdges }
}));
}
}
}, [initialData]); }, [initialData]);
// 实时更新 canvasDataMap
useEffect(() => {
if (initialData?.id) {
updateCanvasDataMapDebounced(dispatch, canvasDataMap, initialData.id, nodes, edges);
}
// 清理函数,在组件卸载时取消防抖
return () => {
updateCanvasDataMapDebounced.cancel();
};
}, [nodes, edges, initialData?.id, dispatch, canvasDataMap]);
// 监听边的变化,处理添加节点的触发 // 监听边的变化,处理添加节点的触发
useEffect(() => { useEffect(() => {
const edgeToAddNode = edges.find(edge => edge.data?.addNodeTrigger); const edgeToAddNode = edges.find(edge => edge.data?.addNodeTrigger);

@ -4,6 +4,7 @@ interface IDEContainerState {
info: any; info: any;
menuData: any; menuData: any;
flowData: any; flowData: any;
canvasDataMap: any;
logBarStatus?: boolean; logBarStatus?: boolean;
} }
@ -11,6 +12,7 @@ const initialState: IDEContainerState = {
info: {}, info: {},
menuData: {}, menuData: {},
flowData: {}, flowData: {},
canvasDataMap: {},
logBarStatus: false logBarStatus: false
}; };
@ -27,12 +29,21 @@ const ideContainerSlice = createSlice({
updateFlowData(state, action) { updateFlowData(state, action) {
state.flowData = { ...state.flowData, ...action.payload }; state.flowData = { ...state.flowData, ...action.payload };
}, },
updateCanvasDataMap(state, action) {
state.canvasDataMap = { ...state.canvasDataMap, ...action.payload };
},
updateLogBarStatus(state, action) { updateLogBarStatus(state, action) {
state.logBarStatus = action.payload; state.logBarStatus = action.payload;
} }
} }
}); });
export const { updateInfo, updateMenuData, updateFlowData, updateLogBarStatus } = ideContainerSlice.actions; export const {
updateInfo,
updateMenuData,
updateFlowData,
updateCanvasDataMap,
updateLogBarStatus
} = ideContainerSlice.actions;
export default ideContainerSlice.reducer; export default ideContainerSlice.reducer;
Loading…
Cancel
Save