๊ฐ์
๋ฏธ์ | ๊ธฐ๊ฐ | Repository | PR & Review | github page |
---|---|---|---|---|
์ ์ฌ ๋ญ ๋จน์ง ๋ฏธ์ 1๋จ๊ณ | 23-04-14 - 23-04-17 | Repo | PR & Review | ๐ ์ ์ฌ ๋ญ ๋จน์ง |
๋ฏธ์ ํ๊ณ
2๋จ๊ณ ๋ฏธ์ ์ ํ์ ์๊ตฌ ์ฌํญ์ 1๋จ๊ณ์ ๋์ผํ์ง๋ง ํ๋ก๊ทธ๋๋ฐ ์๊ตฌ์ฌํญ์ ๋ค์๊ณผ ๊ฐ์ด ์์ ๋์๋ค.
1. Step1์ Class Component๋ฅผ Function Component๋ก ๋ง์ด๊ทธ๋ ์ด์ ํ๋ค.
2. Custom Hooks์ ์ด์ฉํ์ฌ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ๊ธฐ๋ฅ์ ๋ถ๋ฆฌํ๋ค.
์ด์ ๋ฐ๋ผ Function Component์ Custom Hooks์ ์ด์ ์ ๋์ด ๋ฏธ์ ์ ์งํํ๋ค.
Function Component์ผ๋ก ๋ง์ด๊ทธ๋ ์ด์ ํ๋ ๊ณผ์ ์ ํฌ๊ฒ ์ด๋ ต์ง ์์๋ค. ๋๊ฐ์ ์์ ์ ๋ฐ๋ณตํ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ๊ธ๋ฐฉ ์๋ฃํ ์ ์์๋ค. ๋ฌธ์ ๋ Custom Hooks์ ๋ง๋๋ ๊ฒ์ ์์๋ค. ์ผ๋จ ๋ฌด์๋ถํฐ ํ ์ผ๋ก ๋ง๋ค์ด์ผ ํ ์ง ๊ฐ์ด ์กํ์ง ์์๋ค. ์ ํธ์ ์๋์ง๋ง ์ฌ๊ธฐ์ ๊ธฐ์์ ์ฌ์ฌ์ฉํ ์ ์๋ ๊ทธ๋ฐ ๊ฒ... ์ํ ๋ณํ๋ฅผ ์ค์ค๋ก ๊ฐ์งํ์ฌ ์๋ก์ด ๋ฌด์ธ๊ฐ๋ฅผ ๋ค์ ๋ฆฌํดํ๋ ๋ฌด์ธ๊ฐ... ๋ง์น ๋ ๋ฒจ 1์์ ๋๋ฉ์ธ์ ์ด๋ป๊ฒ ๋๋์ด์ผ ํ๋๊ฐ? ์ด ์ญํ ์ ๋๊ฐ ์ฑ ์์ ๊ฐ์ ธ์ผ ํ๋๊ฐ? ์ ๊ฐ์ ๊ณ ๋ฏผ์ ์ฐ์์ด์๋ค. ๋ ๋ง์ ๊ณ ๋ฏผ์ ํตํด ๊ฒฐ๋ก ์ ๋์ถํด๋ ์ข์ง๋ง, ์ผ๋จ ์ฐ์ต์ด๋ผ๋ ์๊ฐ์ผ๋ก ๋ฆฌ์คํธ๋ฅผ ํํฐ๋งํ๋ ๋ถ๋ถ์ ํ ์ผ๋ก ๋ง๋ค์๋ค. ์ด ๋ถ๋ถ์ ์๋์์ ์์ธํ ๋ค๋ฃฌ๋ค.
2๋จ๊ณ์์๋ ์ฑ์ title๊ณผ favicon๋ ์์ ํ์๋ค. ์ค์ ๋ก ๋ฐฐํฌ๋๊ณ ์ฌ์ฉ์๊ฐ ์๋ ์๋น์ค๋ ์๋์ง๋ง, public๋ด์ ํ์ผ์ ์ ๋ฆฌํ๋ฉด์ index.html์ ๋ด์ฉ๋ ์๋น์ค์ ์ฑ๊ฒฉ์ ๋ง๊ฒ ๋ณ๊ฒฝํ์๋ค. ๋๋ฆ? ๊ด์ฐฎ์ ๋ณด์ธ๋ค.
Class Component์์ Function Component์ผ๋ก ์ ๋ฐ๋์๋์ง(์ด์ ๋ฐ๋ฅธ ์ฅ์ ์ ๋ฌด์์ธ์ง), Custom Hooks๋ ์? ์ธ์ ? ๋ฑ๊ณผ ๊ฐ์ ๋ถ๋ถ์์ ์์ง ํ์ต์ด ๋ถ์กฑํ๋ค. ์ ๋ฆฌํด์ผ๊ฒ ์ง?
๐ ํด๋ ๊ตฌ์กฐ
ํด๋ ๊ตฌ์กฐ๊ฐ ๋๋์ ์ผ๋ก ๋ฐ๋์๋ค๊ณ ํด๋ ๊ณผ์ธ์ด ์๋๋ค. ์ด์ ์ ํด๋ ๊ตฌ์กฐ์ ๋ฐ๋ ๋ถ๋ถ์ ๋ค์๊ณผ ๊ฐ๋ค.
1. ๊ฐ๋ณ์ ์ธ ์ปดํฌ๋ํธ ํด๋ ์์ฑ
2. ์คํ์ผ ์ปดํฌ๋ํธ ๋ถ๋ฆฌ
์ด์ ๊ฐ์ด ํด๋ ๊ตฌ์กฐ๋ฅผ ๋ณ๊ฒฝํ ์ด์ ๋ ๋ค์๊ณผ ๊ฐ๋ค.
1. ์ปดํฌ๋ํธ ๋ณ๋ก ํด๋๋ฅผ ๋ง๋ค์ด ๊ฐ์ ์ฃผ์ ์ ๊ด๋ จํ ํ์ผ์ ํ ๊ณณ์์ ๊ด๋ฆฌํ๋ค. (์คํ์ผ๊ณผ ์์ผ๋ก ์ถ๊ฐ๋ ํ ์คํธ ์ฝ๋ ๋ฑ)
2. ๋ฆฌ์กํธ ์ปดํฌ๋ํธ์์ ์คํ์ผ์ ๊ด๋ จ๋ ์ฝ๋๋ฅผ ์ ๊ฑฐํ๋ค. (์คํ์ผ ์ปดํฌ๋ํธ๋ฅผ ๋งจ ์๋๋ก ๋ด๋ฆฌ๊ณ ์ถ์ง ์์๋ค.)
์ง๊ธ์ ํ์ด์ง๊ฐ ์์ด page์ ๊ดํ component๊ฐ ์๋ค. ๋๋ฌธ์ ํ์ฌ ํด๋น ์ญํ ์ restaurant ํด๋๊ฐ ํ๊ณ ์๋ค. ์์ผ๋ก page๊ฐ ์ถ๊ฐ๋๋ค๋ฉด page ํด๋ ํ์์ ํด๋(page์ด๋ฆ)๋ฅผ ๋ง๋ค๊ณ ํด๋น ํด๋์์ page์์ ์ฌ์ฉ๋๋ ์ปดํฌ๋ํธ๋ฅผ ๊ด๋ฆฌํ ์์ ์ด๋ค. components ํด๋๋ ์ด๋ค page์์๋ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์ปดํฌ๋ํธ๋ฅผ ๋ชจ์๋๋ฉด ์ข์ ๊ฒ ๊ฐ๋ค. ์ด๋ ๊ฒ ๋๋ฉด common ํด๋๋ ํ์ ์์ ๊ฒ์ด๋ค.
โญ๏ธ Custom Hook
๋ฌด์์ ํ ์ผ๋ก ๋ถ๋ฆฌํ ๊น? ์ด๋ป๊ฒ ํ๋ฉด ๋ค๋ฅธ ์ปดํฌ๋ํธ์์๋ ์ ์ฐํ๊ฒ ์ฌ์ฉํ ์ ์์๊น? ํ๋ ๊ณ ๋ฏผ์ 2๋จ๊ณ ๋ฏธ์ ์์ ๊ฐ์ฅ ์ค๋ซ๋์ ํ๋ค. ๊ทธ๋์ ๋ด๋ฆฐ ๊ฒฐ๋ก ์ '๋น์ฅ์ ํ ์ผ๋ก ๋ฐ๋ก ๋ถ๋ฆฌํ ๊ฒ์ ์๋ค.'์๋ค. ๋ง์ฝ ์๋น์ค๊ฐ ์ปธ๋๋ผ๋ฉด ๋ถ๋ช ์ค๋ณต๋๋ ๊ฒ์ด ์์์ ๊ฒ์ด๊ณ ํด๋น ๊ธฐ๋ฅ์ ํ ์ผ๋ก ๋ถ๋ฆฌํ์ ๊ฒ์ด๋ค. ์๋ฅผ ๋ค์ด, ๋ชจ๋ฌ์ฐฝ์ด ์ด๋ ค์๋์ง ๋ซํ์๋์ง, ํํฐ๋ง๋ ๋ฆฌ์คํธ๋ฅผ ๋ณด์ฌ์ฃผ๋ ๊ฒ ๋ฑ๋ฑ...
๊ทธ๋๋ ์ฐ์ต ๊ฒธ ํ ์ ๋ถ๋ฆฌํ์๋ค. ์ ์ฌ ๋ญ ๋จน์ง์์ ๋ง๋ ํ ์ useListFiltering์ด๋ค. list(๋ฐฐ์ด)๊ณผ ํํฐ๋งํ๋ ๊ฐ์ฒด๋ฅผ ๋ฐ๋๋ค. ํํฐ๋งํ๋ ๊ฐ์ฒด์ ํค๋ ํํฐ๋ง์ ์ฃผ์ , ๊ฐ์ ํํฐ๋ง ํจ์์ด๋ค. ํด๋น ํ ์ ํตํด ์ด๋ค ๋ฆฌ์คํธ๋ฅผ ํํฐ๋งํ ์ ์๋ค.
โฌ๏ธ ๋ฒ์ฉ์ฑ์ด ๋จ์ด์ง๋ useListFiltering
์์ฑ๋ ์ฝ๋๋ฅผ ๋ณด๊ธฐ ์ , ๋ฒ์ฉ์ฑ์ด ๋จ์ด์ง๋ useListFiltering๋ถํฐ ์ดํด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
type FilterFnCallbackFn = (_res: Restaurant[]) => Restaurant[]; // ์์์ ๋ชฉ๋ก์ ๋ฐํํ๋ ์ฝ๋ฐฑ๋ง ๋ฐ์ ์ ์๋ค.
type FilteringFn = Record<string, FilterFnCallbackFn>; // ํํฐ๋ง ๊ฐ์ฒด์ ํค๊ฐ์ด string์ด๋ค.
const useFilteringList = (
list: Restaurant[], // ๋งค๊ฐ๋ณ์๋ก ์์์ ๋ชฉ๋ก ๋ฆฌ์คํธ๋ง ๋ฐ์ ์ ์๋ค.
filteringFn: FilteringFn,
): [Restaurant[], (subject: string, filteringFn: FilterFnCallbackFn) => void] => {
const [_filteringFn, setFilteringFn] = useState(filteringFn);
const filteringPipe = () => {
return Object.values(_filteringFn).reduce((_list, fn) => fn(_list), list);
};
// subject๊ฐ string์ด๊ธฐ ๋๋ฌธ์ ์๋ชป๋ ๊ฐ์ ๋ฐ์ผ๋ฉด ์์ํ์ง ๋ชปํ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ์ ์ ์๋ค.
const changeFilteringFn = (subject: string, filteringFn: FilterFnCallbackFn) => {
// ...
};
return [filteringPipe(), changeFilteringFn];
};
export default useFilteringList;
์ useFilteringList ํ ์ 2๊ฐ์ง ๋ฌธ์ ๋ฅผ ๊ฐ์ง๊ณ ์๋ค.
1. ์์์ ๋ชฉ๋ก ๋ฆฌ์คํธ๊ฐ ์๋ ๋ค๋ฅธ ๋ฆฌ์คํธ์ ๋ํด ํํฐ๋ง์ ํ ์ ์๋ค.
2. ์์์ ๋ชฉ๋ก ๋ฆฌ์คํธ๋ฅผ ๋ฐํํ๋ ์ฝ๋ฐฑ๋ง ๋ฐ์ ์ ์๋ค.
3. ํํฐ๋ง ํจ์์ ํค๊ฐ string์ด๊ธฐ ๋๋ฌธ์ ์๋ชป๋ subject๋ฅผ ๋๊ฒผ์ ๋, ์ํ์ง ์๋ ๊ฒฐ๊ณผ๊ฐ ๋ํ๋ ์ ์๋ค.
๊ฒฐ๊ตญ ์์์ ๋ชฉ๋ก์๋ง ํ์ ๋์ด useFilterinfList๋ฅผ ์ฌ์ฉํ ์ ์๋ค. ์ด๋ ๊ฒ ๋๋ฉด ์ฌ๋ฌ ์ปดํฌ๋ํธ์์ ์ฌ์ฌ์ฉํ ์ ์๋ ํ ์ด ๋ ์ ์๋ค.
ํ์ฌ ์ ์ฌ ๋ญ ๋จน์ง ์๋น์ค์๋ ์ง๊ธ๋ง์ผ๋ก๋ ์ถฉ๋ถํ์ง๋ง ๋ฒ์ฉ์ฑ์ ๋์ฌ ์ด๋ ํ ๋ฆฌ์คํธ๊ฐ ๋ค์ด์๋ ํํฐ๋ง๋ ๋ฆฌ์คํธ๋ฅผ ๋ณด์ฌ์ค ์ ์๋๋ก ๊ฐ์ ํ๊ณ ์ถ์๋ค. ์ฐ์ต์ด๋๊น ๐
โฌ๏ธ ๋ฒ์ฉ์ฑ์ ๋์ธ useFilteringList
๋ฒ์ฉ์ฑ์ ๋์ด๊ธฐ ์ํด ํ์ ์คํฌ๋ฆฝํธ์ ์ ๋ค๋ฆญ์ ์ฌ์ฉํ์๋ค. ์ด ์ ๋ค๋ฆญ ๋๋ฌธ์ ์ฃผ๋ง์ ์ ๋ฐ์ด ๋ ์๊ฐ๋ค. ๊ฐ์ ๋ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ๋ค.
import { useState } from 'react';
type FilterFnCallbackFn<T> = (arg: T) => T;
type FilterFn<K, U> = Record<keyof K, U>;
const useFilteringList = <List, CallBackFn extends FilterFnCallbackFn<List>, K extends FilterFn<K, CallBackFn>>(
list: List,
filteringFn: FilterFn<K, CallBackFn>,
): [List, (subject: keyof K, filteringFn: FilterFnCallbackFn<List>) => void] => {
const [_filteringFn, setFilteringFn] = useState(filteringFn);
const filteringPipe = () => {
return (Object.values(_filteringFn) as CallBackFn[]).reduce((_list, fn) => fn(_list), list);
};
const changeFilteringFn = (subject: keyof K, filteringFn: FilterFnCallbackFn<List>) => {
// ...
};
return [filteringPipe(), changeFilteringFn];
};
export default useFilteringList;
์ค๊ฐ์ ๋จ์ธ๋ฌธ์ด ๋ณด์ด๊ธด ํ์ง๋ง,, ์ผ๋จ์ ์ ์ ๋์ํ๋ค. List, CallBackFn, K์ ๊ฐ์ ์ ๋ค๋ฆญ์ ์ฌ์ฉํ์ฌ ์ด๋ค ๋ฆฌ์คํธ, ํํฐ๋ง ํจ์๊ฐ ๋ค์ด์ค๋๋ผ๋ ์ ์ฐํ๊ฒ ๋์ฒํ ์ ์๊ฒ ๋์๋ค.
๋ค์์ useFilteringList ํ ์ ๊ฐ๋จํ ์์์ด๋ค.
type Friend = { name: string; age: number; gender: string }[];
const friend = [
{ name: 'HD', age: 30, gender: '๋จ์' },
{ name: 'KH', age: 28, gender: '์ฌ์' },
{ name: 'YB', age: 31, gender: '๋จ์' },
{ name: 'GY', age: 32, gender: '๋จ์' },
{ name: 'SJ', age: 29, gender: '์ฌ์' },
];
const friendFiltering = {
gender: (list: Friend) => list.filter((item) => item.gender === '๋จ์'),
age: (list: Friend) => list.sort((a, b) => a.age - b.age),
};
const [list] = useFilteringList(friend, friendFiltering);
console.log(list);
// {name: 'HD', age: 30, gender: '๋จ์'}
// {name: 'YB', age: 31, gender: '๋จ์'}
// {name: 'GY', age: 32, gender: '๋จ์'}
์ ๋ค๋ฆญ ์ฌ์ฉ์ ์ต์ํ์ง ์์ ์๊ฐ์ด ์ค๋ ๊ฑธ๋ ธ๋ค. ์ผ๋จ ๋์๊ฐ๊ฒ๋์ ํ์ง๋ง ๊ณผ์ฐ ์ ์ฌ์ฉํ๋์ง ์๋ฌธ์ด ๋ ๋ค. ์์ผ๋ก ํ ์ ๋ง๋ค ๋, ์ ๋ค๋ฆญ์ ์ฌ์ฉํ์ฌ ์ฐ์ต์ ์์ฃผ ํด๋ณด์.
๐ 1๋จ๊ณ, 2๋จ๊ณ ์ฝ๋ ๋ฆฌ๋ทฐ ๋ด์ฉ
๋ฆฌ์กํธ ์ปดํฌ๋ํธ์ ์คํ์ผ ์ปดํฌ๋ํธ
์คํ์ผ ์ปดํฌ๋ํธ์ ๋ฆฌ์กํธ ์ปดํฌ๋ํธ๋ฅผ ํ๋์ ํ์ผ์ ์์ฑํ๊ฒ ๋๋ฉด ์ฝ๋๊ฐ 100์ค์ด ๋๋ ๊ฒฝ์ฐ๊ฐ ์๊ธด๋ค. ์ด๋ ๊ฐ์ธ์ ์ธ ํ๋จ์ผ๋ก ๊ฐ๋ ์ข๋ค. ์ฆ, ์ฝ๋์ ๊ธธ์ด๊ฐ ๊ธธ์ด๋ ํ๋์ ํ์ผ์์ ์์ฑํ๋ ๊ฒ์ด ์ข์ผ๋ฉด ํ๋์ ํ์ผ์ ์์ฑํ๊ณ ๊ธด ์ฝ๋๊ฐ ๋ถํธํ๋ค๋ฉด ๋ถ๋ฆฌํ์ฌ๋ ์ข๋ค.
์ด์ ํจ๊ป ๋ ์๊ฐํ ๋ถ๋ถ์ ์ฌ๋๋ค์ด ์ฝ๋๋ฅผ ์ฝ์์ ๋, ๋ฆฌ์กํธ ์ปดํฌ๋ํธ์ ์คํ์ผ ์ปดํฌ๋ํธ ์ค ์ด๋ค ์ปดํฌ๋ํธ๋ฅผ ๋จผ์ ๋ณด๊ณ ์ถ์ด ํ๋์ง์ด๋ค. ์๋ฌด๋๋ ๋ฆฌ์กํธ ์ปดํฌ๋ํธ์ด์ง ์์๊น ์ถ๋ค. ๋๋ฌธ์ ์คํ์ผ ์ปดํฌ๋ํธ๋ฅผ ํ๋จ์ผ๋ก ์ฎ๊ธฐ๊ฑฐ๋ ํ์ผ์ ๋ถ๋ฆฌํ๋ ๊ฒ์ด ์ข๋ค๊ณ ์๊ฐํ๋ค.
ํผ๋๋ฐฑ์ ๋ฐ๊ณ ๋ ์ดํ, ์คํ์ผ ์ปดํฌ๋ํธ์ ๋ฆฌ์กํธ ์ปดํฌ๋ํธ๋ฅผ ๋ถ๋ฆฌํ์๋ค. ๊ฐ๊ฐ์ ๊ด์ฌ์ฌ๋ฅผ ๋ถ๋ฆฌํ์๋ค. ์คํ์ผ๋ ํ๋ก ํธ๋ฅผ ๋ค๋ฃจ๋ ์ ์ฅ์์ ์ค์ํ ๋ถ๋ถ์ด๊ธฐ ๋๋ฌธ์ ๋ฌด์์ด ๋ ์ค์ํ๋ค๊ณ ํ ์ ์๋ค. ๋ชจ๋ ๋ค ์ค์ํ๊ธฐ ๋๋ฌธ์ ๊ฐ๊ฐ์ ํ์ผ์์ ๊ด๋ฆฌํ๊ธฐ๋ก ํ๋ค. ์ถ๊ฐ๋ก ๋ฆฌ์กํธ ์ปดํฌ๋ํธ์ ์คํ์ผ ์ปดํฌ๋ํธ๋ฅผ ๊ตฌ๋ถํ๊ธฐ ์ํด ์คํ์ผ ์ปดํฌ๋ํธ๋ฅผ ๋ถ๋ฌ์ค๊ธฐ ์ํด ๋ค์๊ณผ ๊ฐ์ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋ค.
import * as S from "./style"
์ด๋ฐ ๋ฐฉ๋ฒ์ผ๋ก ์คํ์ผ ์ปดํฌ๋ํธ ์์ S. ์ ๋ถ์ฌ ๋ฆฌ์กํธ ์ปดํฌ๋ํธ์ ๊ตฌ๋ถํ ์ ์๋ค. ํ์ง๋ง S ์์ฒด๊ฐ Style์ธ์ง? State์ธ์ง? ๊ตฌ๋ถ์ ํ๋ ๊ฒ์ด ์ข๊ธฐ ๋๋ฌธ์ ์ด์ ๋ํด์ ์กฐ๊ธ ๋ ๊ณ ๋ฏผํด์ผ ํ๋ค.
setState๋ฅผ ์ด๋ป๊ฒ ์์ ์ปดํฌ๋ํธ์ ๋๊ธธ๊น?
setState๋ฅผ ์์ ์ปดํฌ๋ํธ์ ๋๊ธฐ๋ ๋ฐฉ๋ฒ์๋ ์ ๋ต์ ์๋ค. ํ์ง๋ง ๋๋ฆ์ ๊ธฐ์ค์ ๋ง๋ค ์ ์๋ค๊ณ ์๊ฐํ๋ค. ๋ค์๊ณผ ๊ฐ์ ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ด ์๋ค. ํ๋๋ ์ํ๋ฅผ ๋ณ๊ฒฝํ๋ setState๋ฅผ ์์ ์ปดํฌ๋ํธ์ ์ ๋ฌํ๋ ๋ฐฉ๋ฒ์ด๊ณ ๋ค๋ฅธ ํ๋๋ setState๋ฅผ ํ์ฉํ ํจ์๋ฅผ ์์ ์ปดํฌ๋ํธ์ ์ ๋ฌํ๋ ๋ฐฉ๋ฒ์ด๋ค.
function App() {
const [state, setState] = useState()
const fn = () => {
setState(something)
}
return (
<>
<Children someProp={setState}/>
<Children someProp={fn}/>
</>
)
}
setState๋ฅผ ํ์ฉํ ํจ์๋ฅผ ์ด๋์์ ์ฌ์ฉํ๋๋์ ๋ฐ๋ผ ๋ฐฉ๋ฒ์ด ๋ฌ๋ผ์ง๋ค. ๋๋ ๋ณดํต์ ๊ฒฝ์ฐ ํจ์๋ฅผ ๋ง๋ค์ด ์ด๋ฅผ ์์ ์ปดํฌ๋ํธ์ ์ ๋ฌํ๋ค.
ํ์ง๋ง ๊ฐ์ setState๋ฅผ ์ฌ์ฉํ๋ฉด์ ์ฌ๋ฌ ๊ฐ์ ์์ ์ปดํฌ๋ํธ์์ ์ฌ์ฉํ๋ ํจ์๊ฐ ๋ค๋ฅด๋ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํ ๊น? ์์ App ์ปดํฌ๋ํธ๋ด์์ ํ๋๊ฐ ์๋ ์ฌ๋ฌ ๊ฐ์ ํจ์(๊ฐ์ setState๋ฅผ ํ์ฉํ ํจ์)๋ฅผ ๋ง๋ค์ด์ผ ํ๋ค. ์ด๋ ๊ฒ ๋๋ค๋ฉด ํ๋์ ์ปดํฌ๋ํธ์ ์ฝ๋์ ์์ ๋ง์์ง ๊ฒ์ด๋ค. ์ด๋ด ๋ setState๋ฅผ ์ ๋ฌํ์ฌ ์์ ์ปดํฌ๋ํธ์์ setState๋ฅผ ์ ๊ฐ๊ธฐ ํ์ฉํ๋ ๊ฒ์ด ์ข์ ๋ณด์ธ๋ค.
ํน์ ํ๋์ ์ปดํฌ๋ํธ์์ ๊ด๋ฆฌํ๊ณ ์๋ ์ํ๊ฐ ๋ง์ ๊ฒฝ์ฐ setState๋ฅผ ํ์ฉํ๋ ํจ์๋ ๋ง์์ง๋ค. ๋น์ทํ ํจ์๊ฐ ๋ง์์ง์๋ก ์ ์ง๋ณด์์ฑ๊ณผ ๊ฐ๋ ์ฑ์ ๋จ์ด์ง๋ค. ๊ทธ๋ฆฌ๊ณ ํด๋ฉด์๋ฌ๋ ๋์ง ์์ ๊ฒ์ด๋ผ๋ ํ์ ์ ์๋ค. ์ด์ ๊ฐ์ ๊ฒฝ์ฐ๋ setState๋ฅผ ์ง์ ์์ ์ปดํฌ๋ํธ์ ๋๊ฒจ ์์ ์ปดํฌ๋ํธ์์ setState๋ฅผ ํ์ฉํ ํจ์๋ฅผ ๋ง๋๋ ๊ฒ์ด ์ข๋ค.(๋ ๋ฒจ 2์ ํ์ด๋จผ์ธ ๋ฏธ์ ์ ์ด์ ๊ฐ์ ๋ฐฉ๋ฒ์ผ๋ก ํ๋ค.)
๋ค์ ๋งํ์ง๋ง ์ ํธ๋์ ์ฐจ์ด์ด๋ค.
CRA๋ฅผ ์ด์ฉํ ๋,
Create React App์ ๋ฆฌ์กํธ ํ๋ก์ ํธ๋ฅผ ์์ฝ๊ฒ ์ฌ์ฉํ ์ ์๋ค. CRA๋ฅผ ์ฌ์ฉํ์ฌ ๋ฆฌ์กํธ๋ฅผ ์์ํ๋ฉด ๊ธฐ๋ณธ์ ์ผ๋ก ์๊ธฐ๋ ํ์ผ์ด ์๋ค. ๋ง์ฝ ํ์ ์๋ ํ์ผ์ด๋ผ๋ฉด ์ง์์ผ ํ๋๋ฐ, ๋ฌด์์ธ์ง ๋ชจ๋ฅด๊ณ ์ง์ธ ์ ์๋ค. ์ด์ค ์์ํ ํ์ผ์ ๋ฌด์์ผ๊น?
- manifest.json: ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ๋ณด๋ฅผ JSON ํ ์คํธ ํ์ผ๋ก ์ ๊ณตํด์ ์น ์ฑ์ ๋ค์ด๋ก๋๋ฅผ ๋ค์ดํฐ๋ธ ์ฑ๊ณผ ์ ์ฌํ ํํ๋ก ์ ๊ณตํ ์ ์๊ฒ ๋์์ค๋ค.
- robots.txt: ๋๋ถ๋ถ์ ์น ์ฌ์ดํธ์ ์์ค ํ์ผ์ ํฌํจ๋์ด ์์ผ๋ฉฐ ์น ํด๋กค๋ฌ(๊ฒ์ ์์ง ๋ด)์ ๊ฐ์ ๋ด์ ํ๋์ ๊ด๋ฆฌํ๊ธฐ ์ํ ํ์ผ
- reportWebVitals.js: React์ ์ฑ๋ฅ ์ธก์ ๋๊ตฌ
- setupTests.js: React Testring library๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํ ํ์ผ
์ฐธ๊ณ ์ฌ์ดํธ - [React] CRA ์์ ํ์ผ ์ ๋ฆฌ
์ถ๊ฐ์ ์ผ๋ก CRA์์๋ ๋๋ถ๋ถ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ dependencies์ ์กด์ฌํ๋ค. ์ด๋ CRA๋ ๋ชจ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ฒ๋ค๋ ์ดํ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ dependencies์ devDependencies์ ๊ตฌ๋ณ์ด ๋ฌด์๋ฏธํ๊ธฐ ๋๋ฌธ์ด๋ค.
์ฐธ๊ณ ์ฌ์ดํธ - CRA์์ ๋ชจ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ dependencies์ ๋ค์ด๊ฐ ์๋ ์ด์ ๋?
<React.Fragment>์ <>
<React.Fragment>๋ DOM์ ๋ณ๋์ ๋ ธ๋๋ฅผ ์ถ๊ฐํ์ง ์๊ณ ์ฌ๋ฌ ์์์ ๊ทธ๋ฃนํํ ์ ์๋ค. ์ด๋ฅผ ๋จ์ถํ์ฌ <>๋ก ์ฌ์ฉํ ์ ์๋ค. ๊ทธ๋ ๋ค๋ฉด ๋จ์ถ ๋ฌธ๋ฒ์ธ <>๋ง ์ฌ์ฉํ๋ฉด ๋ ๊น? ๊ทธ๊ฒ์ ์๋๋ผ๊ณ ํ๋ค. ๋ณดํต์ ๊ฒฝ์ฐ์ <>๋ฅผ ์ฌ์ฉํ๊ฒ ์ง๋ง, Fragments์ key๊ฐ ์๋ค๋ฉด <React.Fragment> ๋ฌธ๋ฒ์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค. ๊ทธ๋์ผ key๋ฅผ ์ฌ์ฉํ์ฌ ๋งคํํ ์ ์์ผ๋๊น ๋ง์ด๋ค.
์ฐธ๊ณ ์ฌ์ดํธ - ๋ฆฌ์กํธ ๊ณต์ ๋ฌธ์: Fragments ๋จ์ถ ๋ฌธ๋ฒ
ํ๋ ๋ ์ถ๊ฐ! ๋ฆฌ์กํธ์ public/index.html๋ฅผ ๋ณด๋ฉด noscript ํ๊ทธ๊ฐ ์๋ค. ์ด๋ ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์ง์ํ์ง ์๋ ๋ธ๋ผ์ฐ์ ์์๋ ์ฑ์ด ๋์ํ์ง ์์ ๋, ์ฌ์ฉ์์๊ฒ ๋ฉ์์ง๋ฅผ ์ ๋ฌํ๋ ์ญํ ์ ํ๋ค. ๋๋ฌธ์ noscript ํ๊ทธ๋ ํ์ํ๋ค.
์คํ์ผ ์ปดํฌ๋ํธ๋ฅผ ํตํด ๊ณตํต ์คํ์ผ ์ฌ์ฌ์ฉํ๊ธฐ
๊ณตํต ์คํ์ผ์ ๊ด๋ฆฌํ๊ธฐ ์ํด ํ๊ทธ์ ํด๋์ค๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ด ์๋ ์คํ์ผ ์ปดํฌ๋ํธ์ css ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ์คํ์ผ์ ๋ง๋ค์ด ์ฌ์ฉํ ์ ์๋ค. ๋ค์์ ๊ณตํต ์คํ์ผ์ด๋ค.
export const textTitle = css`
font-size: 20px;
line-height: 24px;
font-weight: 600;
`;
export const textSubTitle = css`
font-size: 18px;
line-height: 28px;
font-weight: 600;
`;
์ด๋ ๊ฒ ๋ง๋ค์ด์ง textTitle, textSubTitle์ ๋ค์๊ณผ ๊ฐ์ด ํ์ฉ๊ฐ๋ฅํ๋ค.
export const RestaurantDistance = styled.span`
${textTitle}
`;
export const RestaurantDescription = styled.p`
${textSubTitle}
`;
๋ฆฌ์กํธ์์ key์๋ index ์ง์ํ๊ธฐ
๋ ๋๋ง ํ ํญ๋ชฉ์ด ๋ณํ์ง ์์ ๊ฒ์ด๋ผ๋ ํ์ ์ ๊ฐ์ง์ง ์๋ ํ index๋ฅผ key๋ก ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ง ์๋ค. ์ฆ, ํญ๋ชฉ์ ์์๊ฐ ๋ฐ๋ ์ ์๋ ๊ฒฝ์ฐ key์ ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ์ข์ง ์๋ค. id์ ๊ฐ์ ๊ณ ์ ํ ๊ฐ์ key๋ก ์ฌ์ฉํ์.
์ฐธ๊ณ ์ฌ์ดํธ - ๋ฆฌ์กํธ ๊ณต์ ๋ฌธ์: ๋ฆฌ์คํธ์ Key
๊ฐ๋ ์ฑ์ ์ํด ์ ๋ค๋ฆญ์ type ์ ์ธ์ ํ์.
๋ค์์ useFilteringList ํ ์ ์ฒ์ ์ ๋ค๋ฆญ ํํ์ด๋ค.
const useFilteringList = <T, U extends (arg: T) => T, K extends Record<keyof K, U>>(
list: T,
filteringFn: Record<keyof K, U>,
): [T, (subject: keyof K, filteringFn: (arg: T) => T) => void] => {
// ...
}
T, U, K์ ๊ฐ์ด ์๋ฏธ๊ฐ ๋ถ๋ถ๋ช ํ ๋ค์ด๋ฐ์ผ๋ก ์ธํด ๊ฐ๋ ์ฑ์ด ๋จ์ด์ง๋ค. ์ด๋ฅผ ๊ฐ์ ํ๊ธฐ ์ํด T, U, K๊ฐ ์๋ ํด๋น ํ์ ์ ๋ช ์ํ ์ ์๋๋ก type ์ ์ธ์ ํด์ผ ํ์.
๐ ์ํ ์
1. ์ค์ค๋ก ํ ์ ๊ตฌํํ์๋ค.
2. ์ ๋ค๋ฆญ์ด ๋๋ ค์ ์ง๋ง ๋์ ํ์๋ค.
3. ํ์ผ๊ตฌ์กฐ์ ๋ํด ๋ง์ ๊ณ ๋ฏผ์ ํ์๋ค.
๐ ์์ฌ์ด ์
1. ๋ฌด์์ ํ ์ผ๋ก ๋ง๋ค์ด์ผ ํ ์ง ์์ง ๊ฐ์ด ์กํ์ง ์๋๋ค.
2. ๊ผผ๊ผผํ๊ฒ ์ฝ๋๋ฅผ ๋ฆฌํฉํฐ๋ง ํ์ง ์์๋ค.
๐ ์์ผ๋ก์ ๊ฐ์ค
1. ์ปค์คํฌ ํ ์ ๊ธฐ์ค์ ์ก์๋ณด์.
2. ์ฝ๋ฉํ ๋ ์ฝ๋ฉ์๋ง ์ง์คํ์.
'๐ ์ฐ์ํํ ํฌ์ฝ์ค > Level2' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๋ ๋ฒจ2 ์ฅ๋ฐ๊ตฌ๋ - Step1 (0) | 2023.05.27 |
---|---|
๋ ๋ฒจ2 ํ์ด๋จผ์ธ - Step3 (0) | 2023.05.15 |
๋ ๋ฒจ2 ํ์ด๋จผ์ธ - Step2 (1) | 2023.05.09 |
๋ ๋ฒจ2 ํ์ด๋จผ์ธ - Step1 (4) | 2023.04.24 |
๋ ๋ฒจ2 ๋ค์, ์ ์ฌ ๋ญ ๋จน์ง - Step 1 (0) | 2023.04.14 |