Skip to content

Commit

Permalink
feat: 데이터 상태에 따른 조건부렌더링 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
Nahee-Park committed May 13, 2022
1 parent ad14352 commit 01dcd2f
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 28 deletions.
1 change: 0 additions & 1 deletion week4/src/common/api/AbstractApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ export abstract class AbstractApi {
}

protected static buildPath(...args: string[]): string {
console.log('>>args', args);
return args.reduce((path, arg) => {
return `${path}/${arg}`;
}, '');
Expand Down
17 changes: 10 additions & 7 deletions week4/src/components/common/ErrorFallback.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import React from 'react';
interface ErrorFallbackProps {
error: Nullable<Error>;
reset: () => void;
}
import styled from 'styled-components';

function ErrorFallback({ error, reset }: ErrorFallbackProps) {
console.log('>>>', error, reset);
return <div>ErrorFallback</div>;
function ErrorFallback() {
return <Styled.Root>에러로 데이터를 불러올 수 없습니다ㅠ</Styled.Root>;
}

export default ErrorFallback;
const Styled = {
Root: styled.section`
color: ${({ theme }) => theme.colors['gray-0']};
font-size: 1rem;
margin-top: 10rem;
`,
};
File renamed without changes.
12 changes: 9 additions & 3 deletions week4/src/components/common/Skeleton.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import React from 'react';

import styled from 'styled-components';
function Loading() {
console.log('로딩중');
return <div>Loading</div>;
return <Styled.Root>Loading...기다려줘...</Styled.Root>;
}

export default Loading;
const Styled = {
Root: styled.section`
color: ${({ theme }) => theme.colors['gray-0']};
font-size: 1rem;
margin-top: 10rem;
`,
};
18 changes: 12 additions & 6 deletions week4/src/components/main/Result.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
import { AllLocationListDataType, AllLocationListResponce } from '@api/LocationApi';
import ErrorFallback from '@components/common/ErrorFallback';
import Loading from '@components/common/Skeleton';
import { StatusType } from '@page/Main';
import React from 'react';
import CardList from './CardList';
import NoResult from './NoResult';
import NoResult from '../common/NoResult';

interface ResultProps {
isEmpty: boolean;
keywordLocationData: AllLocationListDataType | undefined;
status: StatusType;
}
function Result({ isEmpty, keywordLocationData }: ResultProps) {
switch (isEmpty) {
case true:
return <NoResult />;
function Result({ isEmpty, keywordLocationData, status }: ResultProps) {
switch (status) {
case 'LOADING':
return <Loading />;
case 'ERROR':
return <ErrorFallback />;
default:
return <CardList keywordLocationData={keywordLocationData} />;
return isEmpty ? <NoResult /> : <CardList keywordLocationData={keywordLocationData} />;
}
}

Expand Down
52 changes: 41 additions & 11 deletions week4/src/page/Main/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import Title from '@components/common/Title';
import { flexColumnCenter } from '@mixin';
import React, { useEffect, useState } from 'react';
import styled from 'styled-components';
import ErrorFallback from '@components/common/ErrorFallback';
import Loading from '@components/common/Skeleton';
import Result from '@components/main/Result';
import { flushSync } from 'react-dom';
export type StatusType = 'IDLE' | 'LOADING' | 'ERROR' | 'COMPLETE';

function Main() {
const [keywordLocationData, setKeywordLocationData] = useState<
Expand All @@ -20,9 +20,27 @@ function Main() {
const [isCheckboxInput, setIsCheckboxInput] = useState(false);
const [searchValue, setSearchValue] = useState('');
const [isEmpty, setIsEmpty] = useState(false);
const [status, setStatus] = useState<StatusType>('IDLE');

const changeStatus = (currentStatus: StatusType) => {
switch (currentStatus) {
case 'IDLE':
flushSync(() => setStatus('IDLE'));
break;
case 'LOADING':
flushSync(() => setStatus('LOADING'));
break;
case 'ERROR':
flushSync(() => setStatus('ERROR'));
break;
default:
flushSync(() => setStatus('COMPLETE'));
break;
}
};

const getLocation = () => {
// 클로저를 이용해 한 번 위치를 받아온 이후엔 불필요한 요청 보내지 않도록
// 클로저를 이용해 한 번 위치를 받아온 이후엔 리렌더하기 이전까지 새로 불러오지 않도록
let _x, _y;
if ('geolocation' in navigator && !_x && !_y) {
return new Promise((resolve) => {
Expand All @@ -38,6 +56,7 @@ function Main() {
(e) => {
alert('현재 위치를 불러올 수 없습니다.');
setIsCheckboxInput(false);
changeStatus('ERROR');
},
);
});
Expand All @@ -47,28 +66,35 @@ function Main() {
};

const fetchSearchResult = async ({ query, page, size, x, y }: getLocationByKeywordProps) => {
console.log('x,y 제대로 들어왔니', x, y);
const currentData = await LocationApi.getLocationByKeyword({ query, page, size, x, y });
console.log('>currentData', currentData);
setKeywordLocationData(currentData?.data);
try {
const currentData = await LocationApi.getLocationByKeyword({ query, page, size, x, y });
setKeywordLocationData(currentData?.data);
} catch (e) {
changeStatus('ERROR');
}
};

const fetchCurrentLocation = async ({ x, y }: getAddressByCoordinteProps) => {
const currentLocation = await LocationApi.getAddressByCoordinte({ x, y });
console.log('>currentLocation', currentLocation);
currentLocation?.data && setSearchValue(currentLocation.data.documents[0]?.address_name);
try {
const currentLocation = await LocationApi.getAddressByCoordinte({ x, y });
currentLocation?.data && setSearchValue(currentLocation.data.documents[0]?.address_name);
} catch (e) {
changeStatus('ERROR');
}
};

const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setSearchValue(e.target.value);
};

const handleClick = async () => {
changeStatus('LOADING');
setIsCheckboxInput((prev) => !prev);
switch (isCheckboxInput) {
case true:
setSearchValue('');
setKeywordLocationData(undefined);
changeStatus('IDLE');
break;
default:
const currentLocation = (await getLocation()) as getAddressByCoordinteProps;
Expand All @@ -80,6 +106,7 @@ function Main() {
x: currentLocation?.x,
y: currentLocation?.y,
});
changeStatus('COMPLETE');
}
};

Expand All @@ -89,7 +116,9 @@ function Main() {
alert('검색어를 입력해주세요');
return;
}
changeStatus('LOADING');
fetchSearchResult({ query: `${searchValue}`, page: 1, size: 15 });
changeStatus('COMPLETE');
};

useEffect(() => {
Expand All @@ -113,6 +142,7 @@ function Main() {
name="isCheckboxInput"
checked={isCheckboxInput}
onClick={handleClick}
readOnly
/>
</Styled.CheckboxInput>
<SearchBar
Expand All @@ -123,7 +153,7 @@ function Main() {
onSubmit={getAddressDataByKeyword}
readOnly={isCheckboxInput}
/>
<Result keywordLocationData={keywordLocationData} isEmpty={isEmpty} />
<Result keywordLocationData={keywordLocationData} isEmpty={isEmpty} status={status} />
</Styled.Root>
);
}
Expand Down

0 comments on commit 01dcd2f

Please sign in to comment.