Skip to content

Commit 08a812b

Browse files
authored
Feat/#380-S : React.lazy + Suspense ์ ์šฉ (#391)
* feat : suspense fallback์— ์ ์šฉ์‹œํ‚ฌ ์›ํฌ์ŠคํŽ˜์ด์Šค skeleton ui ๊ตฌํ˜„ * feat : route ๋ณ„ React.lazy ๋ฐ Suspense ์ ์šฉ * chore : ์ž๋™ import sorting * chore : page index ํŒŒ์ผ ์‚ญ์ œ * perf : ๋กœ๊ณ , ๋ฒ„๋ธ” ์•„์ด์ฝ˜ jpg๋กœ ๋ณ€๊ฒฝ * refactor : ์Šค์ผˆ๋ ˆํ†ค UI์— ๊ธฐ์กด ๋ ˆ์ด์•„์›ƒ๋งŒ ๊ฐ€์ ธ์˜ค๋„๋ก ๋ณ€๊ฒฝ
1 parent e22b9f0 commit 08a812b

File tree

13 files changed

+168
-262
lines changed

13 files changed

+168
-262
lines changed

โ€Žclient/src/App.tsxโ€Ž

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,30 @@
1-
import { useEffect, useState } from 'react';
1+
import { lazy, Suspense, useEffect, useState } from 'react';
22
import { Route, Routes, useLocation, useNavigate } from 'react-router-dom';
33
import { getAuth } from 'src/apis/auth';
44
import UserContext from 'src/contexts/user';
5-
import {
6-
LoadingPage,
7-
LoginPage,
8-
NotFoundPage,
9-
OAuthPage,
10-
WorkspacePage,
11-
} from 'src/pages';
125
import { User } from 'src/types/user';
136

147
import 'styles/reset.scss';
158
import MetaHelmet from './components/MetaHelmet';
169

10+
const LoginPage = lazy(() => import('src/pages/Login'));
11+
const OAuthPage = lazy(() => import('src/pages/OAuth'));
12+
const WorkspacePage = lazy(() => import('src/pages/Workspace'));
13+
const NotFoundPage = lazy(() => import('src/pages/404'));
14+
const LoadingPage = lazy(() => import('src/pages/Loading'));
15+
1716
function App() {
1817
const [user, setUser] = useState<User | null>(null);
19-
const [isLoaded, setIsLoaded] = useState<boolean>(false);
2018

2119
const location = useLocation();
2220
const navigate = useNavigate();
2321

2422
const autoLogin = async () => {
2523
const { user } = await getAuth();
2624

27-
setIsLoaded(true);
28-
2925
setUser(user);
3026

31-
if (user && !/^\/workspace(\/\d)?$/.test(location.pathname)) {
27+
if (user && !/^\/workspace(\/\d+)?$/.test(location.pathname)) {
3228
navigate('/workspace');
3329
}
3430
};
@@ -40,7 +36,7 @@ function App() {
4036
return (
4137
<>
4238
<MetaHelmet title="ํ™”์ƒํšŒ์˜์™€ ํšŒ์˜๋ก ์ž‘์„ฑ์„ ํ•œ๋ฒˆ์—, Wabinar" />
43-
{isLoaded ? (
39+
<Suspense fallback={<LoadingPage />}>
4440
<UserContext.Provider value={{ user, setUser }}>
4541
<Routes>
4642
<Route path="/" element={<LoginPage />} />
@@ -49,9 +45,7 @@ function App() {
4945
<Route path="/404" element={<NotFoundPage />} />
5046
</Routes>
5147
</UserContext.Provider>
52-
) : (
53-
<LoadingPage />
54-
)}
48+
</Suspense>
5549
</>
5650
);
5751
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import style from './style.module.scss';
2+
3+
function MomSkeleton() {
4+
return (
5+
<div className={style['mom-container']}>
6+
<div className={style['mom']}>
7+
<div className={style['mom-header']}></div>
8+
<div className={style['mom-body']}></div>
9+
</div>
10+
</div>
11+
);
12+
}
13+
14+
export default MomSkeleton;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import style from './style.module.scss';
2+
3+
function SideBarSkeleton() {
4+
return (
5+
<div className={style['sidebar-container']}>
6+
<div className={style['header']}></div>
7+
<div className={style['member-list']}></div>
8+
<div className={style['mom-list-container']}></div>
9+
</div>
10+
);
11+
}
12+
13+
export default SideBarSkeleton;

โ€Žclient/src/components/Sidebar/style.module.scssโ€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
display: flex;
1414
flex-direction: column;
1515
align-items: center;
16-
min-width: 240px;
16+
width: 300px;
1717
height: 100vh;
1818
overflow: hidden;
1919
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import MomSkeleton from 'src/components/Mom/Skeleton';
2+
import SideBarSkeleton from 'src/components/Sidebar/Skeleton';
3+
import WorkspaceListSkeleton from 'src/components/WorkspaceList/Skeleton';
4+
5+
import style from './style.module.scss';
6+
7+
function WorkspaceSkeleton() {
8+
return (
9+
<div className={style['workspace-sk']}>
10+
<WorkspaceListSkeleton />
11+
<SideBarSkeleton />
12+
<MomSkeleton />
13+
</div>
14+
);
15+
}
16+
17+
export default WorkspaceSkeleton;
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
@import 'styles/color.module';
2+
3+
@mixin loading {
4+
@keyframes loading {
5+
0% {
6+
background-color: $gray-300-transparent;
7+
}
8+
50% {
9+
background-color: $gray-300;
10+
}
11+
100% {
12+
background-color: $gray-300-transparent;
13+
}
14+
}
15+
16+
animation: loading 1.2s infinite ease-out;
17+
}
18+
19+
.workspace-sk {
20+
display: flex;
21+
width: 100%;
22+
height: 100%;
23+
24+
.side-bar-sk {
25+
display: flex;
26+
flex-direction: column;
27+
min-width: 240px;
28+
height: 100%;
29+
padding: 20px;
30+
.name {
31+
@include loading();
32+
width: 90%;
33+
height: 20px;
34+
margin-bottom: 20px;
35+
}
36+
.members {
37+
@include loading();
38+
width: 80%;
39+
height: 20px;
40+
margin-bottom: 20px;
41+
}
42+
.moms {
43+
@include loading();
44+
width: 60%;
45+
height: 20px;
46+
}
47+
}
48+
.mom-sk {
49+
display: flex;
50+
flex-direction: column;
51+
align-items: center;
52+
justify-content: flex-end;
53+
width: 100%;
54+
height: 100vh;
55+
56+
.head {
57+
display: flex;
58+
align-items: center;
59+
justify-content: center;
60+
width: 90%;
61+
height: 60px;
62+
margin-bottom: 20px;
63+
padding: 5px 0;
64+
65+
.title {
66+
@include loading();
67+
width: 50%;
68+
height: 30px;
69+
}
70+
.date {
71+
@include loading();
72+
width: 20%;
73+
height: 20px;
74+
margin-top: auto;
75+
margin-left: auto;
76+
}
77+
}
78+
.mom {
79+
@include loading();
80+
position: relative;
81+
width: 90%;
82+
height: calc(100% - 30px);
83+
}
84+
}
85+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import style from './style.module.scss';
2+
3+
function WorkspaceListSkeleton() {
4+
return <div className={style['workspace-list-container']}></div>;
5+
}
6+
7+
export default WorkspaceListSkeleton;

โ€Žclient/src/components/common/Icon/Bubbles/index.tsxโ€Ž

Lines changed: 4 additions & 193 deletions
Large diffs are not rendered by default.

โ€Žclient/src/components/common/Icon/Logo/index.tsxโ€Ž

Lines changed: 4 additions & 29 deletions
Large diffs are not rendered by default.

โ€Žclient/src/pages/Workspace/index.tsxโ€Ž

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,22 @@
1-
import Workspace from 'components/Workspace';
2-
import { useEffect, useState } from 'react';
1+
import DefaultWorkspace from 'components/Workspace/DefaultWorkspace';
2+
import WorkspaceSkeleton from 'components/Workspace/Skeleton';
3+
import { lazy, Suspense, useEffect, useState } from 'react';
34
import { Route, Routes, useNavigate, useParams } from 'react-router-dom';
45
import { getWorkspaces } from 'src/apis/user';
5-
import DefaultWorkspace from 'src/components/Workspace/DefaultWorkspace';
66
import WorkspacesContext from 'src/contexts/workspaces';
77
import useUserContext from 'src/hooks/context/useUserContext';
8-
import LoadingPage from 'src/pages/Loading';
98
import { Workspace as TWorkspace } from 'src/types/workspace';
109

11-
import Layout from './Layout';
12-
1310
function WorkspacePage() {
11+
const Layout = lazy(() => import('./Layout'));
12+
const Workspace = lazy(() => import('components/Workspace'));
13+
1414
const { user } = useUserContext();
1515

1616
const params = useParams();
1717
const navigate = useNavigate();
1818

1919
const [workspaces, setWorkspaces] = useState<TWorkspace[]>([]);
20-
const [isLoaded, setIsLoaded] = useState<boolean>(false);
2120

2221
const loadWorkspaces = async () => {
2322
if (!user) {
@@ -31,8 +30,6 @@ function WorkspacePage() {
3130
id: userId,
3231
});
3332

34-
setIsLoaded(true);
35-
3633
setWorkspaces(userWorkspaces);
3734

3835
if (!userWorkspaces.length) {
@@ -53,18 +50,16 @@ function WorkspacePage() {
5350
}, []);
5451

5552
return (
56-
<WorkspacesContext.Provider value={{ workspaces, setWorkspaces }}>
57-
{isLoaded ? (
53+
<Suspense fallback={<WorkspaceSkeleton />}>
54+
<WorkspacesContext.Provider value={{ workspaces, setWorkspaces }}>
5855
<Routes>
5956
<Route path="/" element={<Layout />}>
6057
<Route index element={<DefaultWorkspace />} />
6158
<Route path="/:id" element={<Workspace />} />
6259
</Route>
6360
</Routes>
64-
) : (
65-
<LoadingPage />
66-
)}
67-
</WorkspacesContext.Provider>
61+
</WorkspacesContext.Provider>
62+
</Suspense>
6863
);
6964
}
7065

0 commit comments

Comments
ย (0)