๋ฌธ์ ์์ ์ปดํฌ๋ํธ ๋ด์์ ํ์ ์ปดํฌ๋ํธ๋ก props๋ฅผ ์ ๋ฌํ๋ ๊ณผ์ ์์ type ์๋ฌ๊ฐ ๋ฐ์ํ์๋ค. export interface InfoType { [key: string]: any; id: number; title: string; client: string; due: string; count: number; amount: number; method: string[]; material: string[]; status: string; } const InfoListForm: FC = ({ method, material, status }) => { ( ... ) return ( {isEmpty ? ( ์กฐ๊ฑด์ ๋ง๋ ๊ฒฌ์ ์์ฒญ์ด ์์ต๋๋ค. ) : ( currentInfoList.map((info: InfoTy..
๋ฌธ์ ์ ์ ๊ฐ ์ ํํ ์์ดํ ์ ์ ๋ณด๋ฅผ ๋ด๊ณ ์๋ ๋ฆฌ์คํธ๋ฅผ ์ํํ์ฌ ํด๋น ์์ดํ ์ด ์กด์ฌํ๋์ง์ ์ฌ๋ถ๋ฅผ ํ์ธํ๊ธฐ ์ํด์ ๋ค์๊ณผ ๊ฐ์ด ๋ฌธ์์ด๋ก ๊ฐ์ฒด์ ํ๋กํผํฐ์ ์ ๊ทผํ๋ ์ฝ๋๋ฅผ ์์ฑํ์๋ค. infoList.forEach((info: InfoType) => { let isSorted = false; for (let i = 0; i < currentSelectedSortNum; i++) { if (info[currentSortName].includes(currentSort[i])) { isSorted = true; break; } } ( ... ) }); ํ์ง๋ง ์ ๋๋ก ๊ธฐ๋ฅ์ด ๋์๋์ง ์์๊ณ ์ค๋ฅ๋ฅผ ํ์ธํ๊ธฐ ์ํด ์ฝ์๋ฅผ ๋ณด๋, ๋ค์๊ณผ ๊ฐ์ ๋ฉ์ธ์ง๊ฐ ๋ ์์๋ค. Element implicitly has an 'any..
๋ฌธ์ ์์์ ๋ค์ด๊ฐ ์์ด์ฝ์ ๋ฃ์ด์ฃผ๊ธฐ ์ํด ๋ค์๊ณผ ๊ฐ์ด ๊ธฐ์กด์ png๋ jpg ํ์ผ์ importํ๋ ๋ฐฉ์์ผ๋ก svg ๋ฆฌ์์ค๋ฅผ ๊ฐ์ ธ์๋ค. import linkBtnImg from '../../../assets/icon-link_to_button.svg'; ํ์ง๋ง ์ด๋ฐ ์์ผ๋ก ์ฌ์ฉํ๋ค ๋ณด๋, ํฌ๊ธฐ๋ง ๋ค๋ฅธ svg๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์ ๋๊ฐ์ ๋ฆฌ์์ค๋ฅผ ๋ ๋ฒ import ํด์ผ ๋๋ ๋ฒ๊ฑฐ๋ก์ด ๋ฌธ์ ๊ฐ ์์๋ค. ๋ฌธ์ ํด๊ฒฐ ์์ ๋ฐฉ์์ด ์๋ svg ์์ฒด๋ฅผ ์ปดํฌ๋ํธํ ์ํค๋ ๋ฐฉ์์ ์ฌ์ฉํ๊ธฐ๋ก ํ์๋ค. ์ฐ์ ๋ค์๊ณผ ๊ฐ์ด ํด๋น svg ํ์ผ์ ReactComponent์ ํํ๋ก import ํด ์จ๋ค. import { ReactComponent as LinkToButton } from '../../../assets/icon-lin..
๋ฌธ์ ์ํฐ๋ ํ๋ฆฌ์จ ๋ณด๋ฉ ์ ๋ณ ๊ณผ์ ์์ Nav๋ฅผ ์ ์ํ๋ ์ค, ๋ ์ด์์ ๊ตฌ์ฑ ๋ชฉ์ ์ผ๋ก flex ๊ด๋ จ ์์ฑ๋ค์ ๊ณ์ ์ฌ์ฉํ๋ ๊ฒ์ ํ์ธํ ์ ์์๋ค. ๋์์ธ์ ์ ์ฉํ๋ ๊ฒ์ ์์ด์ ๋ฌธ์ ๋ ์์ง๋ง ๋ฐ๋ณต๋๋ ์ฝ๋๋ฅผ ์ค์ฌ ์คํ์ผ์ ์ ์ฉํ ์ ์๋์ง ๊ณ ๋ฏผํ๊ฒ ๋์๊ณ scss์์ variable์ ๋ณ๋๋ก ๋ถ๋ฆฌํ์ฌ ๊ณตํต ์คํ์ผ ์์ฑ์ ์ ์ํ๋ ๊ฒ๊ณผ ๊ฐ์ด styled-components์์ ์ฌ์ฉํ ๋ณ์ ๋ชจ์ ๊ฐ์ฒด์ธ theme์ ์ด์ฉํ์ฌ flex ๊ด๋ จ minin ํจ์๋ฅผ ์ฌ์ฉํด ๋ณด๊ธฐ๋ก ํ์๋ค. Code themeProvider๋ก ์ ์ญ ๋ณ์๋ก ์ฌ์ฉ๋๋ theme ๋ด๋ถ์ flex ์์ฑ์์ ์์ฃผ ์ฌ์ฉ๋๋ mixin ์์ฑ์ ํจ์ ํํ๋ก ๋ค์๊ณผ ๊ฐ์ด ์ ์ํ์๋ค. const theme = { flexMinin: (direction ..
Issue ํ์ฌ ํ๋ก์ ํธ ๋์ค, ์ฌ์ฉ์์ ์ธ์ฆ/์ธ๊ฐ๋ฅผ ํตํด ์๋น์ค๋ฅผ ๊ตฌ์ถํ๊ธฐ ์ํด ์๋ฒ๋ก๋ถํฐ ๋ฐ๊ธ ๋ฐ์ JWT ํ ํฐ์ ์ด๋์ ์ ์ฅํด์ผ ๋ ์ง ๋ง์ ๊ณ ๋ฏผ์ด ์์๋ค. ์ฒ์์๋ store์ ๋ฐ๊ธ ๋ฐ์ JWT ํ ํฐ์ ์ ์ฅํด์ฃผ๋ ๋ฐฉ์์ผ๋ก ์งํํ์๋๋ฐ, JWT ํ ํฐ์ด ํ์ํ ์ํฉ๋ง๋ค ๋งค๋ฒ store์ ์ ์ฅ๋์ด ์๋ ๊ฐ์ useSelector()๋ฅผ ํตํด ๊ฐ์ ธ์ค๋ ๊ฒ์ ์ ์ฒด ์ฝ๋๋ฅผ ๋ฒ์กํ๊ฒ ๋ง๋๋ ๋ฌธ์ ๊ฐ ์์๋ค. ๋ณด์์์ ์ด์๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด ๋ฐฑ์๋ ์ธก๊ณผ ์ํตํ์ฌ refresh token์ ์ฌ์ฉํ๋ ๋ฐฉ์์ด ๊ฐ์ฅ ์ข์๊ฒ ์ง๋ง ๋น์ ๋ฐฑ์๋ ๊ฐ๋ฐ์์ ์ํฉ์ด ์ฌ์์น ์์๊ธฐ ๋๋ฌธ์ ํด๋ผ์ด์ธํธ ์ธก์์ ํ ์ ์๋ ์ต์ ์ ๋ฐฉ๋ฒ์ ์ ํํ๊ธฐ๋ก ํ์๋ค. ์ด์ ๋ฐ๊ธ ๋ฐ์ JWT ํ ํฐ์ localstorage์ ์ ์ฅํ๋ ๋ฐฉ์์ ํ๋ก์ ํธ์ ์ ๋ชฉ..
๋ฌธ์ ์๋ฒ์์ API ํต์ ๋์ค ๋น๋๊ธฐ์ ์ฒ๋ฆฌ์ ์ธ์๊ณผ ์ ์ด๋ฅผ ํจ์จ์ ์ผ๋ก ํ๊ธฐ ์ํด ๋ค์๊ณผ ๊ฐ์ด redux-saga ๋ฏธ๋ค์จ์ด๋ฅผ ์ด์ฉํ ์ ํธ ํจ์๋ฅผ ๋ง๋ค์๋ค. export const createRequestActionTypes = type => { const SUCCESS = `${type}_SUCCESS`; const FAILURE = `${type}_FAILURE`; return [type, SUCCESS, FAILURE]; }; export default function createRequestSaga(type, request) { const SUCCESS = `${type}_SUCCESS`; const FAILURE = `${type}_FAILURE`; return function* (action)..
๋ฌธ์ ํน์ ํ์ด์ง์ ๋ค์ด๊ฐ์ ๊ฒฝ์ฐ, ์กฐ๊ฑด๋ถ ๋๋๋ง์ ํด์ฃผ๊ธฐ ์ํด์ react-router-dom ๋ด matchPath()๋ฅผ ์ฌ์ฉํ์ฌ ๋ค์๊ณผ ๊ฐ์ด ์ฝ๋๋ฅผ ์์ฑํ ๊ฒฝํ์ด ์์๋ค. const TopNav = () => { const navigate = useNavigate(); const location = useLocation(); const isAuthView = () => { const currentPathname = location.pathname; if ( matchPath(currentPathname, { path: "/login" }) || matchPath(currentPathname, { path: "/login" }) ) return true; else return false; }; if (..
ํ๊ณ https://programmers.co.kr/competitions/2165/2022-web-fe-first 2022 Dev-Matching: ์น ํ๋ก ํธ์๋ ๊ฐ๋ฐ์(์๋ฐ๊ธฐ) ์ ์ 22๋ 02์ 21์ผ 10:00 ~ 03์ 10์ผ 17:00 ํ ์คํธ 22๋ 03์ 12์ผ 14:00 ~ 03์ 12์ผ 17:00 programmers.co.kr 2022.03.12 Dev-Matching ํ ์คํธ๋ฅผ ๋ณด์๋ค.์ฐ๋ คํ๋ ๊ฒ๋ณด๋จ ํ ์คํธ์ ๋์ด๋๊ฐ ํฌ๊ฒ ์ด๋ ต์ง ์์์ง๋ง ํ๋์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฌ์ฉ์ ์ต์ํด ์๋ ๋์๊ฒ, ์ค๋๋ง์ Vanilla JS๋ง์ผ๋ก ์ดํ๋ฆฌ์ผ์ด์ ๊ตฌํํ๋ ๊ณผ์ ์ด ์กฐ๊ธ ๋ฏ์ค์๋ค. ํ ์คํธ๊ฐ ๋๋ ๋ค, ์ด๋ ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋งน๋ชฉ๋์ง ์๊ณ ๊ธฐ๋ฐ์ด ๋๋ JS๋ฅผ ๋์ ์์ด ํ์ตํด์ผ ๊ฒ ๋ค๋ ์์ง๋ฅผ ๋์๊ฒผ๋ค. ์ด์ ํ ..