1. ๐ซ Custom Hook
1) ๋๋ฌด๋๋ ๊ถ๊ธํ๋ ๋ด์ฉ ๋๋์ด!
์ ๋ฒ ๋ด์คํผ๋ ํ๋ก์ ํธ ํ ๋ ๊ณ์ํด์ input๊ฐ์ ํธ๋ค๋งํ๋ hook๋ค์ ๋ฐ๋ณต์ ์ผ๋ก ์ฌ์ฉํ๋๋ฐ ์ด๊ฑธ ์ด๋ป๊ฒ ํ๋ฉด ๋ ํด๋ฆฐํ๊ฒ ๋ฆฌํฉํ ๋ง ํ ์ ์์์ง ๊ณ ๋ฏผ์ ํ์๋ค.
2) ์ฌ์ฉ๋ฐฉ๋ฒ
- hooks ํด๋ ์์ฑ ํ use~๋ก ์์ํ๋ (ex. useHookName.js) ํ์ผ ์์ฑ
- useState, useEffect, useRef ๋ฑ ๊ธฐ์กด ๋ฆฌ์กํธ ํ
์ ์ด์ฉํด์ ๋ฐ๋ณต์ ์ผ๋ก ์ฌ์ฉํ๋ ๋ก์ง์ custom hook์ผ๋ก ๋ง๋ค์ด์ค๋ค.
โก๏ธ ์ด ๋, custom hook์๋ state์ handler ๋ ๊ฐ์ง๋ฅผ ์ ์ํด์ค๋ค. - export default ํด์ค ๋ค ํ์ํ ๊ณณ์์ importํ์ฌ ์ฌ์ฉํ๋ฉด ๋!
// useInput.js (์์)
import { useState } from "react";
const useInput = () => {
// state
const [value, setValue] = useState('');
// handler
const handler = (e) => {
setValue(e.target.value)
}
return [value, handler];
};
export default useInput;
// import React, { useState } from "react";
import useInput from "../hooks/useInput";
import SignUp from "./SignUp";
const App = () => {
// 1. custom hook ์ฌ์ฉ
const [name, onChangeNameHandler] = useInput();
const [password, onChangePasswordHandler] = useInput();
// 2. ์ด์ ๊น์ง ํด์๋ ๊ธฐ์กด ๋ฐฉ์
// const [name, setName] = useState('');
// const [password, setPassword] = useState('');
// const onChangeNameHandler = (e) => {
// setName(e.target.value);
// }
// const onChangePasswordHandler = (e) => {
// setPassword(e.target.value);
// }
return (
<>
<h1>Custom Hooks</h1>
<input type="text" value={name} onChange={onChangeNameHandler} />
<input type="password" value={password} onChange={onChangePasswordHandler}/>
<div>
<SignUp />
</div>
</>
);
};
export default App;
3) ์ฅ์
- ์ฝ๋์ ๋ฐ๋ณต ์ฌ์ฉ์ ์ค์ฌ์ฃผ๊ธฐ ๋๋ฌธ์ ์ฝ๋๊ฐ ๊ฐ๊ฒฐํด์ง
- ๊ฐ๋ ์ฑ, ์ ์ง๋ณด์์ฑ ์ฐจ์์์๋ good!
2. ๐ช Container - Presentational ํจํด
์ปดํฌ๋ํธ๋ฅผ ๋ ๊ฐ์ ๊ณ์ธต์ผ๋ก ๋ถ๋ฆฌํ๋ ํจํด
- JavaScript(๊ธฐ๋ฅ)๊ณผ JSX(UI)๋ก ๋๋๋ ๋ฐฉ๋ฒ
๋ญ์ผ ๊ทธ๋ฅ ํํ ๋ฆฌ์กํธ ์ปดํฌ๋ํธ ์์?
- Container : JavaScript ์์ญ, UI๋ฅผ ๊ตฌ์ฑํ๊ณ ๋ณํ์ํค๊ธฐ ์ํ ๊ธฐ๋ฅ ๋ก์ง์ ์ง์คํ๋ ๊ณ์ธต
- Presentational : JSX ์์ญ, ์ฌ์ฉ์์๊ฒ ๋ณด์ด๋ UI๊ฐ ์ด๋ป๊ฒ ๊ตฌ์ฑ๋์ด์ผ ํ๋์ง์๋ง ์ง์คํ๋ ๊ณ์ธต
- Presentational์ Container๋ก ๊ฐ์ผ ํ์ ํ์ํ ์ ๋ณด์ ๋ก์ง๋ค์ props๋ก ์ ๋ฌํด์ฃผ๋ ํํ
React 16.8 ์ดํ Hook์ ๋ฑ์ฅ์ผ๋ก, ์ ์ฌ์ฉํ์ง๋ ์๋ ํจํด์ด๋ผ๊ณ ํจ
3. ๐๏ธ ํ์ผ/ํด๋ ๊ตฌ์กฐ(ํจํด)
Custom hook์ useState, useEffect ๋ฑ ๋ฆฌ์กํธ ํ ์ ์ฌ์ฉํ์ฌ ๋ฐ๋ณต์ ์ผ๋ก ์ฌ์ฉํ๋ ๊ฒ๋ค์ ์ปค์คํ ํ ์ผ๋ก ๋ง๋ค์ด์ค๋ค๋ ๊ฒ์ ์ดํดํ์.
์ ๋ถํฐ ๊ถ๊ธํ๋ ๊ฑด, '๋ ์ง ํ์ ๋ณํ'์ด๋ '๋น๋ฐ๋ฒํธ ์ ํจ์ฑ ๊ฒ์ฌ' ๊ฐ์ ๊ธฐ๋ฅ๋ค์ ์ ๋งํ ์น์๋น์ค์์ ํํ๊ฒ ๋ฐ๋ณต์ ์ผ๋ก ์ฌ์ฉํ๋ ๋ก์ง์ธ๋ฐ ์ด๋ฐ ๊ฑด ์ด๋ป๊ฒ ํธ๋ค๋งํ ๊น?
1) ํจ์ ๋ชจ๋๋ก ๊ด๋ฆฌ
์์ - timestamp๋ฅผ 2023. 7. 5 12:07 ํํ๋ก ์ฐ๊ณ ์ถ์ผ๋ฉด?
formatTime.js๋ผ๋ ์ค๋ํซ ๋ชจ๋ jsํ์ผ ์์ฑ ํ, ์ฌ์ฉํ๋ ์ปดํฌ๋ํธ์ importํด์ ๊ฐ๋ค ์ฐ๊ธฐ
// formatTime.js
const formatTime = (timestamp) => {
const date = new Date(timestamp);
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
const hour = date.getHours().toString().padStart(2, '0');
const minute = date.getMinutes().toString().padStart(2, '0');
return `${year}. ${month}. ${day} ${hour}:${minute}`
};
export default formatTime;
// ContentsList.jsx
import React from 'react';
import formatTime from './formatTime';
const ContentsList = () => {
// ...
return (
<>
...
{*/ ์ฌ๊ธฐ์ todo.createdAt์ timestamp ํ์/*}
"๊ธ ์ด ์๊ฐ" : {formatTime(todo.createdAt)}
</>
);
}
export default ContentsList;
2) ํ์ผ/ํด๋ ๋ถ๋ฅ ๊ตฌ์กฐ, ํด๋๋ช ์ปจ๋ฒค์
๐ฆsrc
โฃ ๐hooks
โ โ ๐useInput.js
โฃ ๐lib
โ โฃ ๐helpers
โ โ โ ๐passwordValidation.js
โ โ โ ๐formatTime.js
โ โฃ ๐services
โ โ ๐utils
โฃ ๐App.jsx
โ ๐index.js
lib, utils, helpers, services
- lib : ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํจ์๋ ๊ณตํต ๋ก์ง์ ๋ณด๊ดํ๋ ํด๋๋ก, ์ผ๋ฐ์ ์ผ๋ก ํ๋ก์ ํธ ์ ์ฒด์์ ์ฌ์ฉ๋๋ ์ฝ๋๋ฅผ ๋ชจ์๋๋ ๊ณณ
- utils / helpers : ์ฌ์ฌ์ฉ ๊ฐ๋ฅ ํจ์, ์ ํธ๋ฆฌํฐ ํจ์, ํฌํผ ํจ์
- services : API ํธ์ถ์ด๋ DB ์ฐ๊ฒฐ ๋ฑ ์๋น์ค ๊ด๋ จ
์ ํธ ํจ์์ ํฌํผ ํจ์
๋์ ๋น์ทํ ๊ฐ๋ ์ธ ๊ฒ ๊ฐ์ผ๋ ์ฐพ์๋ณธ ์ฐจ์ด์ ์ผ๋ก๋ ๋ค์๊ณผ ๊ฐ์ (์คํ์ค๋ฒํ๋ก์ฐ์ธ๊ฐ ์์ด ์ฌ์ดํธ ๋ฒ์ญํ๊ฑฐ๋ผ ์ฝ๊ฐ ์ด์)
- utils : ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฒด์์ ์ฌ์ฉํ ์ ์๋ ์์ ์ค๋ํซ์ ๋ฐฐ์นํ ์ ์๋ ๊ณณ. utils์์์ ์์ ๋ชจ๋๋ก ๋ ํฐ ์ปดํฌ๋ํธ๋ฅผ ๊ตฌ์ฑํ ์ ์์
- helpers: ์ฝ๋ ์ํคํ ์ฒ ์ค๋ํซ์ ์ ์ฅํ๋ ๊ณต๊ฐ์ ๊ฐ๊น๋ค๊ณ ๋ณด๋ฉด ๋จ. ์ปดํฌ๋ํธ ๋ถํธ์คํธ๋ฉ๊ณผ ๊ฐ๋ฐ์ ์ธ์ฒด๊ณตํ(=๊ฐ๋ฐ์๋ค์ด ํ์์ ํ์๋ก ํ๋ ๊ธฐ๋ฅ๊ณผ ๋์์ธ์ ๋ํ ๊ฒ๋ค)์ ํ์์ ์ธ ๊ฒ๋ค
Utils | Helpers | |
๋ชฉ์ | ํ๋ก๊ทธ๋จ์ ํน์ ๋ถ๋ถ์ ์ฐ๊ฒฐ๋์ง ์์ ์ผ๋ฐ ๋๋ ์ผ๋ฐ ์์ ์ํ | ํ๋ก๊ทธ๋จ์ ๋ค๋ฅธ ๋ถ๋ถ์ ๋ํ ์ง์ ๋๋ ์์กฐ ์ ๊ณต |
๋ฒ์ | ํ๋ก๊ทธ๋จ ์ ์ฒด ๋๋ ์ฌ๋ฌ ํ๋ก๊ทธ๋จ์์ ์ฌ์ฉ ๊ฐ๋ฅ | ์ผ๋ฐ์ ์ผ๋ก ํน์ ๋ชจ๋ ๋๋ ํ๋ก๊ทธ๋จ์ ์ผ๋ถ ๋ด์์ ์ฌ์ฉ |
์์กด์ฑ | ์ผ๋ฐ์ ์ผ๋ก ํ๋ก๊ทธ๋จ์ ๋ค๋ฅธ ๋ถ๋ถ๊ณผ ๋ ๋ฆฝ์ | ํ๋ก๊ทธ๋จ์ ๋ค๋ฅธ ๋ถ๋ถ์ด๋ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์์กดํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ |
์์ | ๋ฌธ์์ด ์กฐ์ ํจ์, ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ฑ | Form ์ ํจ์ฑ ๊ฒ์ฌ ํจ์, ๋ฐ์ดํฐ ํฌ๋งทํ ๋ฑ |
'โ๏ธ What I Learned > TIL' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[TIL] TypeScript ์ธ์ด์ ํ์ ๋ฐฐ๊ฒฝ ๊ธฐ๋ณธ์ ์ธ ํน์ง (0) | 2023.07.25 |
---|---|
[TIL] React Query ์ธํ , isLoading/isError, staleTime vs. cacheTime (0) | 2023.07.17 |
[WIL] ํ ํ๋ก์ ํธ ํ๊ณ (React ๋ด์คํผ๋ ํ๋ก์ ํธ) (0) | 2023.07.04 |
[TIL] Git / GitHub์ ๋ํด ์ ๋ฆฌ (0) | 2023.06.30 |
[TIL] .env ํ๊ฒฝ๋ณ์ ํ์ผ (0) | 2023.06.27 |