Skip to content

Commit 509ead9

Browse files
committed
feat: api 분리, loader 추가
1 parent 54949f2 commit 509ead9

File tree

9 files changed

+116
-106
lines changed

9 files changed

+116
-106
lines changed

src/apis/index.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
const API_DOMAIN = 'https://jsonplaceholder.typicode.com';
2+
3+
export const fetchComments = () => {
4+
return fetch(`${API_DOMAIN}/comments`, {
5+
method: 'GET',
6+
}).then((res) => res.json());
7+
};
8+
9+
export const fetchPhotos = () => {
10+
return fetch(`${API_DOMAIN}/photos`, {
11+
method: 'GET',
12+
}).then((res) => res.json());
13+
};

src/components/ImageListItem/index.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
margin-right: 20px;
1212

1313
img {
14-
max-width: 150px;
14+
max-width: 180px;
1515
}
1616
}
1717
}

src/components/ImageListItem/index.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@ const ImageListItem = ({ index, imageUrl, title, onLoad }: Props) => {
1515
</section>
1616
<section>
1717
<p>index: {index}</p>
18-
<p>
19-
{title} {title} {title} {title} {title} {title}
20-
</p>
18+
<p>{Array.from({ length: 10 }).map(() => title)}</p>
2119
</section>
2220
</div>
2321
);

src/components/Loader/index.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { Spinner, Box } from '@chakra-ui/react';
2+
3+
const Loader = () => {
4+
return (
5+
<Box textAlign="center" margin={6}>
6+
<Spinner speed="0.65s" emptyColor="gray.200" color="blue.500" size="lg" />
7+
</Box>
8+
);
9+
};
10+
11+
export default Loader;

src/components/TextListItem/index.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@ const TextListItem = ({ index, email, name, body }: Props) => {
1313
<p>index: {index}</p>
1414
<p>email: {email}</p>
1515
<p>name: {name}</p>
16-
<p>
17-
body: {body} {body}
18-
</p>
16+
<p>body: {Array.from({ length: 2 }).map(() => body)}</p>
1917
</div>
2018
);
2119
};

src/pages/ImageList/index.tsx

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { useEffect, useState, useCallback } from 'react';
22
import { checkInfiniteScrollPosition } from '../../helpers/scroll';
33
import { throttle } from 'lodash-es';
4+
import { fetchPhotos } from '../../apis';
45

56
import { Container, Heading, Button, Text } from '@chakra-ui/react';
6-
import StackSkleton from '../../components/StackSkeleton';
7+
import StackSkeleton from '../../components/StackSkeleton';
78
import ImageListItem from '../../components/ImageListItem';
89

910
export interface ImageListItemState {
@@ -21,16 +22,9 @@ const ImageList = () => {
2122
const [list, setList] = useState<ImageListItemState[]>([]);
2223

2324
const fetchData = useCallback(async () => {
24-
// const res = await fetch('https://jsonplaceholder.typicode.com/photos');
25-
// console.log('res :>> ', res);
26-
fetch('https://jsonplaceholder.typicode.com/photos').then((res) => {
27-
const data = res.json();
28-
29-
data.then((newList) => {
30-
totalList = newList;
31-
addList();
32-
});
33-
});
25+
const response = await fetchPhotos();
26+
totalList = response;
27+
addList();
3428
}, []);
3529

3630
const addList = useCallback(() => {
@@ -75,11 +69,13 @@ const ImageList = () => {
7569

7670
<section>
7771
{list.length ? (
78-
list.map(({ title, thumbnailUrl }, index) => (
79-
<ImageListItem index={index} imageUrl={thumbnailUrl} title={title} />
80-
))
72+
<>
73+
{list.map(({ title, url }, index) => (
74+
<ImageListItem key={index} index={index} imageUrl={url} title={title} />
75+
))}
76+
</>
8177
) : (
82-
<StackSkleton count={5} />
78+
<StackSkeleton count={5} />
8379
)}
8480
</section>
8581
</>

src/pages/ImageListVirtualized/index.tsx

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ import { useEffect, useState, useCallback, useRef } from 'react';
22
import { WindowScroller, CellMeasurer, CellMeasurerCache, AutoSizer, List, ListRowProps } from 'react-virtualized';
33
import { checkInfiniteScrollPosition } from '../../helpers/scroll';
44
import { throttle } from 'lodash-es';
5+
import { fetchPhotos } from '../../apis';
56

6-
import { ImageListItemState, SPLICE_SIZE } from '../ImageList';
77
import { Container, Heading, Button, Text } from '@chakra-ui/react';
8+
import { CheckCircleIcon } from '@chakra-ui/icons';
9+
import { ImageListItemState, SPLICE_SIZE } from '../ImageList';
810
import ImageListItem from '../../components/ImageListItem';
9-
import StackSkleton from '../../components/StackSkeleton';
11+
import StackSkeleton from '../../components/StackSkeleton';
1012

1113
const cellCache = new CellMeasurerCache({
12-
defaultWidth: 100,
1314
fixedWidth: true,
1415
});
1516

@@ -20,14 +21,15 @@ const ImageListVirtualized = () => {
2021
const listRef = useRef<List>(null);
2122

2223
const rowRenderer = ({ index, key, parent, style }: ListRowProps) => {
24+
const { title, url } = list[index];
2325
return (
2426
<CellMeasurer cache={cellCache} parent={parent} key={key} columnIndex={0} rowIndex={index}>
2527
{({ measure }) => (
2628
<div style={style} key={index}>
2729
<ImageListItem
2830
index={index}
29-
imageUrl={list[index].thumbnailUrl}
30-
title={list[index].title}
31+
title={title}
32+
imageUrl={url}
3133
onLoad={measure} // 중요: measure 함수로 이미지가 로드된 이후 재 측정을 해주어야 정확한 사이즈로 랜더링됩니다.
3234
/>
3335
</div>
@@ -37,16 +39,9 @@ const ImageListVirtualized = () => {
3739
};
3840

3941
const fetchData = useCallback(async () => {
40-
// const res = await fetch('https://jsonplaceholder.typicode.com/photos');
41-
// console.log('res :>> ', res);
42-
fetch('https://jsonplaceholder.typicode.com/photos').then((res) => {
43-
const data = res.json();
44-
45-
data.then((newList) => {
46-
totalList = newList;
47-
addList();
48-
});
49-
});
42+
const response = await fetchPhotos();
43+
totalList = response;
44+
addList();
5045
}, []);
5146

5247
const addList = useCallback(() => {
@@ -79,7 +74,7 @@ const ImageListVirtualized = () => {
7974
<>
8075
<Container padding={0} marginBottom={5} textAlign="center">
8176
<Heading size="md" mb={5} textAlign="center">
82-
react-virtualized (O)
77+
react-virtualized (<CheckCircleIcon color="green.500" />)
8378
</Heading>
8479
<Button mb={5} colorScheme="blue" onClick={addList}>
8580
목록 추가하기
@@ -114,7 +109,7 @@ const ImageListVirtualized = () => {
114109
)}
115110
</WindowScroller>
116111
) : (
117-
<StackSkleton count={5} />
112+
<StackSkeleton count={5} />
118113
)}
119114
</section>
120115
</>

src/pages/TextList/index.tsx

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { useEffect, useState, useCallback, Fragment } from 'react';
22
import { checkInfiniteScrollPosition } from '../../helpers/scroll';
33
import { throttle } from 'lodash-es';
4+
import { fetchComments } from '../../apis';
45

56
import { Container, Heading, Button, Text } from '@chakra-ui/react';
6-
import StackSkleton from '../../components/StackSkeleton';
7+
import StackSkeleton from '../../components/StackSkeleton';
78
import TextListItem from '../../components/TextListItem';
9+
import Loader from '../../components/Loader';
810

911
export interface TextListItemState {
1012
id: number;
@@ -13,27 +15,18 @@ export interface TextListItemState {
1315
body: string;
1416
}
1517

16-
let isFetching: boolean = false;
17-
1818
const TextList = () => {
1919
const [list, setList] = useState<TextListItemState[]>([]);
20+
const [isFetching, setFetching] = useState<boolean>(false);
2021

21-
const addList = useCallback(() => {
22-
isFetching = true;
23-
fetch('https://jsonplaceholder.typicode.com/comments').then((res) => {
24-
const data = res.json();
22+
const addList = useCallback(async () => {
23+
setFetching(true);
2524

26-
data.then((newList) => {
27-
setList([...list, ...newList]);
28-
isFetching = false;
29-
});
30-
});
25+
const response = await fetchComments();
26+
setList([...list, ...response]);
27+
setFetching(false);
3128
}, [list, setList]);
3229

33-
useEffect(() => {
34-
addList();
35-
}, []);
36-
3730
const onScroll = useCallback(() => {
3831
if (isFetching) {
3932
return false;
@@ -43,7 +36,11 @@ const TextList = () => {
4336
if (isNeedFetching) {
4437
addList();
4538
}
46-
}, [addList]);
39+
}, [isFetching, addList]);
40+
41+
useEffect(() => {
42+
addList();
43+
}, []);
4744

4845
useEffect(() => {
4946
const onScrollTrottle = throttle(onScroll, 100);
@@ -67,13 +64,16 @@ const TextList = () => {
6764

6865
<section>
6966
{list.length ? (
70-
list.map(({ name, email, body }, index) => (
71-
<Fragment key={index}>
72-
<TextListItem index={index} email={email} name={name} body={body} />
73-
</Fragment>
74-
))
67+
<>
68+
{list.map(({ name, email, body }, index) => (
69+
<Fragment key={index}>
70+
<TextListItem index={index} email={email} name={name} body={body} />
71+
</Fragment>
72+
))}
73+
{isFetching && <Loader />}
74+
</>
7575
) : (
76-
<StackSkleton count={5} />
76+
<StackSkeleton count={5} />
7777
)}
7878
</section>
7979
</>

0 commit comments

Comments
 (0)