refactor(project-view): optimize component with useMemo and useCallback for performance improvements
- Introduced useMemo and useCallback to memoize tab menu items and callback functions, enhancing performance. - Added resetProjectData function to clean up project state on component unmount. - Refactored the component to use React.memo for preventing unnecessary re-renders.
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState, useMemo, useCallback } from 'react';
|
||||||
import { PushpinFilled, PushpinOutlined, QuestionCircleOutlined } from '@ant-design/icons';
|
import { PushpinFilled, PushpinOutlined, QuestionCircleOutlined } from '@ant-design/icons';
|
||||||
import { Badge, Button, ConfigProvider, Flex, Tabs, TabsProps, Tooltip } from 'antd';
|
import { Badge, Button, ConfigProvider, Flex, Tabs, TabsProps, Tooltip } from 'antd';
|
||||||
import { useLocation, useNavigate, useParams, useSearchParams } from 'react-router-dom';
|
import { useLocation, useNavigate, useParams, useSearchParams } from 'react-router-dom';
|
||||||
@@ -43,6 +43,14 @@ const ProjectView = () => {
|
|||||||
const [pinnedTab, setPinnedTab] = useState<string>(searchParams.get('pinned_tab') || '');
|
const [pinnedTab, setPinnedTab] = useState<string>(searchParams.get('pinned_tab') || '');
|
||||||
const [taskid, setTaskId] = useState<string>(searchParams.get('task') || '');
|
const [taskid, setTaskId] = useState<string>(searchParams.get('task') || '');
|
||||||
|
|
||||||
|
const resetProjectData = useCallback(() => {
|
||||||
|
dispatch(setProjectId(null));
|
||||||
|
dispatch(resetStatuses());
|
||||||
|
dispatch(deselectAll());
|
||||||
|
dispatch(resetTaskListData());
|
||||||
|
dispatch(resetBoardData());
|
||||||
|
}, [dispatch]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (projectId) {
|
if (projectId) {
|
||||||
dispatch(setProjectId(projectId));
|
dispatch(setProjectId(projectId));
|
||||||
@@ -59,9 +67,13 @@ const ProjectView = () => {
|
|||||||
dispatch(setSelectedTaskId(taskid || ''));
|
dispatch(setSelectedTaskId(taskid || ''));
|
||||||
dispatch(setShowTaskDrawer(true));
|
dispatch(setShowTaskDrawer(true));
|
||||||
}
|
}
|
||||||
}, [dispatch, navigate, projectId, taskid]);
|
|
||||||
|
|
||||||
const pinToDefaultTab = async (itemKey: string) => {
|
return () => {
|
||||||
|
resetProjectData();
|
||||||
|
};
|
||||||
|
}, [dispatch, navigate, projectId, taskid, resetProjectData]);
|
||||||
|
|
||||||
|
const pinToDefaultTab = useCallback(async (itemKey: string) => {
|
||||||
if (!itemKey || !projectId) return;
|
if (!itemKey || !projectId) return;
|
||||||
|
|
||||||
const defaultView = itemKey === 'tasks-list' ? 'TASK_LIST' : 'BOARD';
|
const defaultView = itemKey === 'tasks-list' ? 'TASK_LIST' : 'BOARD';
|
||||||
@@ -88,9 +100,9 @@ const ProjectView = () => {
|
|||||||
}).toString(),
|
}).toString(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
}, [projectId, activeTab, navigate]);
|
||||||
|
|
||||||
const handleTabChange = (key: string) => {
|
const handleTabChange = useCallback((key: string) => {
|
||||||
setActiveTab(key);
|
setActiveTab(key);
|
||||||
dispatch(setProjectView(key === 'board' ? 'kanban' : 'list'));
|
dispatch(setProjectView(key === 'board' ? 'kanban' : 'list'));
|
||||||
navigate({
|
navigate({
|
||||||
@@ -100,9 +112,9 @@ const ProjectView = () => {
|
|||||||
pinned_tab: pinnedTab,
|
pinned_tab: pinnedTab,
|
||||||
}).toString(),
|
}).toString(),
|
||||||
});
|
});
|
||||||
};
|
}, [dispatch, location.pathname, navigate, pinnedTab]);
|
||||||
|
|
||||||
const tabMenuItems = tabItems.map(item => ({
|
const tabMenuItems = useMemo(() => tabItems.map(item => ({
|
||||||
key: item.key,
|
key: item.key,
|
||||||
label: (
|
label: (
|
||||||
<Flex align="center" style={{ color: colors.skyBlue }}>
|
<Flex align="center" style={{ color: colors.skyBlue }}>
|
||||||
@@ -144,21 +156,17 @@ const ProjectView = () => {
|
|||||||
</Flex>
|
</Flex>
|
||||||
),
|
),
|
||||||
children: item.element,
|
children: item.element,
|
||||||
}));
|
})), [pinnedTab, pinToDefaultTab]);
|
||||||
|
|
||||||
const resetProjectData = () => {
|
const portalElements = useMemo(() => (
|
||||||
dispatch(setProjectId(null));
|
<>
|
||||||
dispatch(resetStatuses());
|
{createPortal(<ProjectMemberDrawer />, document.body, 'project-member-drawer')}
|
||||||
dispatch(deselectAll());
|
{createPortal(<PhaseDrawer />, document.body, 'phase-drawer')}
|
||||||
dispatch(resetTaskListData());
|
{createPortal(<StatusDrawer />, document.body, 'status-drawer')}
|
||||||
dispatch(resetBoardData());
|
{createPortal(<TaskDrawer />, document.body, 'task-drawer')}
|
||||||
};
|
{createPortal(<DeleteStatusDrawer />, document.body, 'delete-status-drawer')}
|
||||||
|
</>
|
||||||
useEffect(() => {
|
), []);
|
||||||
return () => {
|
|
||||||
resetProjectData();
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ marginBlockStart: 80, marginBlockEnd: 24, minHeight: '80vh' }}>
|
<div style={{ marginBlockStart: 80, marginBlockEnd: 24, minHeight: '80vh' }}>
|
||||||
@@ -170,33 +178,11 @@ const ProjectView = () => {
|
|||||||
items={tabMenuItems}
|
items={tabMenuItems}
|
||||||
tabBarStyle={{ paddingInline: 0 }}
|
tabBarStyle={{ paddingInline: 0 }}
|
||||||
destroyInactiveTabPane={true}
|
destroyInactiveTabPane={true}
|
||||||
// tabBarExtraContent={
|
|
||||||
// <div>
|
|
||||||
// <span style={{ position: 'relative', top: '-10px' }}>
|
|
||||||
// <Tooltip title="Members who are active on this project will be displayed here.">
|
|
||||||
// <QuestionCircleOutlined />
|
|
||||||
// </Tooltip>
|
|
||||||
// </span>
|
|
||||||
// <span
|
|
||||||
// style={{
|
|
||||||
// position: 'relative',
|
|
||||||
// right: '20px',
|
|
||||||
// top: '10px',
|
|
||||||
// }}
|
|
||||||
// >
|
|
||||||
// <Badge status="success" dot className="profile-badge" />
|
|
||||||
// </span>
|
|
||||||
// </div>
|
|
||||||
// }
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{createPortal(<ProjectMemberDrawer />, document.body, 'project-member-drawer')}
|
{portalElements}
|
||||||
{createPortal(<PhaseDrawer />, document.body, 'phase-drawer')}
|
|
||||||
{createPortal(<StatusDrawer />, document.body, 'status-drawer')}
|
|
||||||
{createPortal(<TaskDrawer />, document.body, 'task-drawer')}
|
|
||||||
{createPortal(<DeleteStatusDrawer />, document.body, 'delete-status-drawer')}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ProjectView;
|
export default React.memo(ProjectView);
|
||||||
|
|||||||
Reference in New Issue
Block a user