Da/shβλ μλΉμ€μ ν΅μ¬ ν€μλμΈ Dance(μΆ€)μ Share(곡μ )λ₯Ό κ²°ν©ν μ΄λ¦μΌλ‘, λμ€ ν΄λμ€μ κ°μ¬λμμ λν μ 보λ₯Ό μμ λ‘κ² νμνκ³ μνλ ν΄λμ€λ₯Ό κ°νΈνκ² μ μ²ν μ μλ νλ«νΌμ λλ€. μ΄ μλΉμ€λ μκ°μκ³Ό κ°μ¬λ₯Ό μ°κ²°νλ λ€λ¦¬ μν μ ν¨κ³Ό λμμ μΈμμ λͺ¨λ λμλ€μ΄ ν¨κ» μν΅νκ³ μ±μ₯ν μ μλ 곡κ°μ μ 곡ν©λλ€.
μ΄μ§ν |
κΉκ·ν |
λ°ν¬μ |
νμμ |
κΉκ±΄ν |
@constantly-dev | @rtttr1 | @heesunee | @hansoojeongsj | @KIMGEONHWI |
main(=master)
: μ€μ§ λ°°ν¬λ₯Ό μν λΈλμΉ β νΉλ³ν μν©μ΄ μλλΌλ©΄ λ°°ν¬λ§ μ§νdevelop
: μμ ν λ΄μ©μ μ·¨ν©νλ κ³³ (default branch)feat(=feature)
: κ° μμ λ¬Όμ λΆκΈ°ν΄ μλ‘ λ§λ€μ΄ μ¬μ©ν λΈλμΉ
Commit λ©μμ§ μ’ λ₯ μ€λͺ
μ λͺ© | λ΄μ© |
---|---|
init |
μ΄κΈ° μΈν (μ΄κΈ° μ΄νλ setting μ¬μ©) |
setting |
ν¨ν€μ§ μ€μΉ, κ°λ° μ€μ |
feat |
μλ‘μ΄ κΈ°λ₯ μΆκ° / νΌλΈλ¦¬μ± |
fix |
λ²κ·Έ μμ |
style |
CSS λ± μ¬μ©μ UI λμμΈ λ³κ²½ |
api |
API μ°κ²° λ‘μ§ μμ± |
refactor |
νλ‘λμ μ½λ 리ν©ν λ§ λ° QA λ°μ |
chore |
λΉλ ν μ€νΈ μ λ°μ΄νΈ, ν¨ν€μ§ 맀λμ μ€μ (νλ‘λμ μ½λ λ³κ²½ X) |
deploy |
λ°°ν¬ μμ |
comment |
νμν μ£Όμ μΆκ° λ° λ³κ²½ |
test |
ν μ€νΈ μΆκ°, ν μ€νΈ 리ν©ν λ§ (νλ‘λμ μ½λ λ³κ²½ X) |
rename |
νμΌ λλ ν΄λ μ΄λ¦ μμ λ° μ΄λ μμ |
remove |
νμΌ μμ μμ λ§ μν |
docs |
λ¬Έμ μμ |
!HOTFIX |
κΈνκ² μΉλͺ μ μΈ λ²κ·Έ μμ |
!BREAKING CHANGE |
컀λ€λ API λ³κ²½ |
src/
μλ ν΄λλ μ λΆ common(곡ν΅)μ μλ―Έλ‘ μκ°νλ€.pages/
μλ μΈλΆ ν΄λ(components, constants λ±λ±)κ° κ°κ° μμΉνλ€.
|-- π .github
|-- π node_modules
|-- π public
|-- π src // src λ°λ‘ νμ ν΄λλ λͺ¨λ common(곡ν΅)μ μλ―Έ
|-- π apis
|-- π common
|-- π νμ΄μ§1
|-- π νμ΄μ§2
|-- π assets
|-- π images
|-- π svg
|-- π components // κ³΅ν΅ μ»΄ν¬λνΈ
|-- π Button
|-- πex) Button.tsx
|-- πex) Button.style.ts
|-- π constants
|-- π hooks
|-- πex) useOutsideClick.ts
|-- π pages
|-- π components
|-- π constants
|-- π types λ± // (νμ΄μ§μ ν΄λΉνλ κ°λ³ λ°μ΄ν° ν΄λ λ°λ‘ μ‘΄μ¬)
|-- π styles
|-- π types
|-- π utils
|-- π routes
|-- index.html λ± ETC
- μ»΄ν¬λνΈ / class
PascalCase
- ν΄λλͺ
carmelCase
- νμΌ λͺ
(μ»΄ν¬λνΈ μ μΈ)
carmelCase
- λ³μ, ν¨μ
carmelCase
- νλΌλ―Έν°
carmelCase
- μμ
BIG_SNAKE_CASE
- interfaceλ νμλ‘
PascalCase
μ¬μ©νλ€. - Props νμ
β
μ»΄ν¬λνΈλͺ +PropTypes
- μμ
interface PostPagePropTypes { title: string | undefined; setTitle: (e: React.ChangeEvent<HTMLTextAreaElement>) => void; tempContent: string; editContent: string; setEditorContent: (content: string) => void; setContentWithoutTag: (content: string) => void; } const PostPage = (props: PostPagePropTypes) => { const {title, setTitle, tempContent, editContent, setEditorContent, setContentWithoutTag ... }
- μμ
- μΌλ° νμ
β
β¦ + Types
- PropsTypesλ μ»΄ν¬λνΈ νμΌ λ΄ / κ·Έ μΈ νμ μ pages/β¦/types ν΄λμ λ°λ‘ λΆλ¦¬
μ»΄ν¬λνΈ Wrapper λ€μ΄λ° κ·μΉ :(λ―Έμ )Wrapper
β (Layout
)βContainer
βBox
- semantic tagλ μ κ·Ή νμ©νλ€.
- **
aria-label
**λ μ κ·Ήμ νμ©!
- **
- SVG νμΌ μ¬μ©μ
- svgrλ‘ μ»΄ν¬λνΈν ν μ¬μ©νλ―λ‘ svgμ΄λ¦μ κ·Έλλ‘ λ³ννμ¬ μ¬μ©νλ€.
-
μ΄λ²€νΈ νΈλ€λ¬ λ€μ΄λ°
handle + κΈ°λ₯ + μ΄λ²€νΈ
- μμ
const handleBtnClick = () => {}; const handleTabChange = () => {};
β propsλ‘ λκΈΈ λ keyκ°μ
on + μ΄λ²€νΈ
- μμ
const BoxComponent = () => { return <memoComponent onClick={handleBtnClick} />; };
- μμ
-
μ νΈ(utils) ν¨μ λ€μ΄λ°
λμ¬(κΈ°λ₯) + λͺ μ¬(λμ)
-
κ°μ΄ booleanμΌ κ²½μ°λ
is + μν
(default)- μμ
const [isLogined, setIsLogined] = useState(false);
β μΆκ°μ μΌλ‘
can / should / has
μ λλ₯Ό μν©μ λ§κ² μΆκ°νλ€. - μμ
-
api ν¨μ
HTTP λ©μλ + λͺ μ¬
- μμ
const getList = () => {}; const getMovie = () => {};
- μμ
-
λ€μ΄λ° μ λ¨μλ₯Ό κΈ°λ³ΈμΌλ‘ μ¬μ©νκ³ / 볡μλ©΄ λ€μ List ν€μλλ₯Ό λΆμΈλ€.
-
assets (Iconμ΄λ Img)μ κ²½μ° νΌκ·Έλ§ λ€μ΄λ°μ μ κ·Ή νμ©νλ€.
β
Ic + νΌκ·Έλ§ λ€μ΄λ°
(iconμ κ²½μ°)μΌλ‘ μ¬μ© -
URL, HTML κ°μ λ²μ©μ μΈ λλ¬Έμ μ½μ΄λ λλ¬Έμ κ·Έλλ‘ μ¬μ©νλ€.
-
λ³μ/μ΅λν μ§κ΄μ μΌλ‘ μμ±νμ¬ λ€μ΄λ°μ λ³΄κ³ λ λ¬΄μ¨ λ°μ΄ν°, νμμΈμ§ λ°λ‘ μ μΆν μ μλλ‘ νλ€.
- μ£Όμμ΄ νμν κ²½μ°μλ μ΄λ€ μν μ νλμ§ λ€λ₯Έ μ¬λμ΄ μ΄ν΄ν μ μλλ‘ μμ±νλ€.
- λ³μ/ν¨μ λͺ μ 20μ λ―Έλ§, μ£ΌμμΌλ‘ λ³μ μ€λͺ
-
μ£Όμμ μμ±νλ €κ³ νλ λμ λ°λ‘ μμ μμ±
- var κΈμ§.
const
βlet
μμλ‘ μλΆν° μ μΈ.- λ³μλ₯Ό μ‘°ν©νμ¬ λ¬Έμμ΄ μμ±μ β+ β κΈμ§. β 리ν°λ΄ μ¬μ©(λ°±ν± ```)
- λ³μλͺ
: μλ―Έλ₯Ό νμ€ν λνλΌ μ μλλ‘
- μμ : λ°°μ΄μ Arr 보λ€λ λ³μs = fruits, userlists λ±λ±
- μ€μλ§ μ°μ§λ§κΈ°. μ΄λ¦μ΄ κΈΈμ΄μ§λλΌλ μ΄λ€ λ³μμΈμ§ μ ννκ²
- μμ : Btn X β ButtonμΌλ‘ μ¬μ©
- map μ¬μ©μ λ³λλλ 리μ€νΈλΌλ©΄ keyκ°μ κ³ μ νκ² μ μ€μ ν΄μ£ΌκΈ°
index μ¬μ© κΈμ§
- μλ²μμ λ΄λ €μ£Όλ idκ° or uuid μ¬μ©
- μ μ λ³μλ λλλ‘ μ¬μ©νμ§ μκΈ°
- νμ΄ν ν¨μ. function ν€μλ μ°μ§λ§κΈ°
- μ€λ³΅ν¨μλ utils ν΄λμ λͺ¨μμ μ¬μ¬μ©νλ€.
- λ³μ/ν¨μ λͺ
μ 20μ λ―Έλ§.
- μ΅λν λ€μ΄λ°μ μλ―Έλ₯Ό λ΄μμ μμ±νκ³ νμ μμ μ£ΌμμΌλ‘ μ€λͺ μΆκ°
- νμνλ€λ©΄ early return ν¨ν΄μ μ κ·Ήμ μΌλ‘ νμ©
- μμ
**// early return ν¨ν΄** function processUser(user) { if (!user || !user.isActive) return; // **μ‘°κ±΄μ΄ λ§μ§ μμΌλ©΄ μΌμ° λ°ν** // λλ¨Έμ§ μ²λ¦¬ μ½λ... }
- μμ
rafce
β κ³ μ - μλ―Έμλ div λλ μ»΄ν¬λνΈ μ΅μλ¨μ fragment μ¬μ©νκΈ°
const InfoText = () => {
return (
<>
<h1>Welcome!</h1>
<p>This our new page, we're glad you're are here!</p>
</>
);
};
- childrenμ΄ λΆνμν λ selfClosingμ¬μ©νκΈ°
<Component/>
- children μ κ·Ήμ μΌλ‘ νμ©νκΈ°!
- object β interface
- λ¨μΌ λ³μ β type alias
- μ»΄ν¬λνΈ μΈμμ λν νμ μ μ»΄ν¬λνΈ μλ¨μ
- κ·Έ μΈμ νμ λ€μ types ν΄λμ
- api response νμ λͺ μ OOOResponseTypes
-
λ°°μ΄ λ³΅μ¬ μ β μ€νλ λ μ°μ°μ(β¦) μ¬μ©
const copys = [β¦originals]
-
for 보λ¨,
forEach
/map
μ μ¬μ© -
ꡬ쑰 λΆν΄ ν λΉμ μ κ·Ή μ΄μ©
interface userDataProps { userName: string; userBirth: string; } function checkIsUser({ userName, userBirth }: userDataProps) {}
-
λΆνμν λ°λ³΅λ¬Έ μ§μ : filter, array.include() λ±
- 쑰건λΆλ‘ λ°μ΄ν°λ₯Ό νμΈνκ±°λ λ½μμΌνλ λ‘μ§μ μ¬μ©ν λμλ
Map
μ΄λObject
μ²λΌkey
κ°μ μ΄μ©ν΄μ μμλ₯Ό μ°Ύλ μλ£νμ μ΄μ©νλκ²μ κ³ λ €ν΄λ³΄κ±°λ, λ°°μ΄μ μννμ§ μκ³ indexλ‘ λ°λ‘ μ κ·Όν μ μλ λ°©λ²μ΄ μλμ§ κ³ λ €.
- 쑰건λΆλ‘ λ°μ΄ν°λ₯Ό νμΈνκ±°λ λ½μμΌνλ λ‘μ§μ μ¬μ©ν λμλ
mozila μΆμ² css μμ (μ°Έκ³ )
β μΆκ° μμ
-
button νκ·Έμ **
type
**μ λͺ μμ μΌλ‘ μμ± -
λΉκ΅ μ°μ°μλ **
===
**μ **!==
**λ§μ μ¬μ© -
axios μμμ
then/catch
λμasync/await
μ§ν₯