Atomic Design 은 가장 작은 단위(Atom)로 부터 컴포넌트를 작성하고, 이러한 컴포넌트들을 결합하여 더 큰 컴포넌트(Molecules, Organisms)를 구성하는 디자인 패턴이다.
Atomic Design 을 폴더 구조에 어떻게 적용할 것인지는 여러가지 방법론이 있다. Atomic 구조 그대로 components 폴더 하위에 atoms 부터 pages 까지 존재하며, 가장 작은 단위를 모두 atoms 에 존재하게 하면서, 이를 조합하게 할 수 있다.
하지만 이럴 경우에, atoms 의 파일들이 많이 쌓일 수 있다. 따라서 특정 organsims 에만 쓰이거나 특정 page 에 쓰이는 컴포넌트는 해당 organsims 또는 page 또는 molecules 하위에 존재하게 하고, 공통으로 쓰이는 컴포넌트만 atoms에 존재하게 하는 방법이 있다.
--components
--atoms
--molecules
--organisms
--templates
--pages
--PageA
--PageB
...
부모컴포넌트가 자식 컴포넌트에게 주는 값. 자식 컴포넌트에서는 props 를 받고, 직접 수정할 수는 없다.
import React, { Component } from 'react';
import PropsExample from './PropsExample';
function App() {
return (
<PropsExample name="리액트" />
);
}
export default App;
다음과 같이 부모 컴포넌트에서 자식 컴포넌트에게 값을 전달하고,
import React from 'react';
const PropsExample = ({ name }) => {
return (
<div>
안녕하세요! 제 이름은 {name} 입니다.
</div>
);
};
export default PropsExample;
과 같이 자식 컴포넌트에서 props 를 받는다.
위의 예시는 js 코드이므로, Type 를 정의하지 않았지만, TypeScript 에서는 Props 의 Type 을 정의하고, Props 를 받아와서 사용한다.
state 는 컴포넌트 자기 자신이 가지고 있는 값이고, 동적인 데이터를 다룰 때 사용한다. setState 함수를 통해서만 변경한다.
React 기본 함수, 이를 이용하면 컴포넌트에서 상태를 관리할 수 있다. 이 함수에 타입을 지정하고 default 값을 인자로 주어 호출하면, array 를 반환하는데, 첫번째 원소는 state 가 저장되는 변수이며, 두번째 원소는 그 변수를 변경할 수 있는 setter 이다.
const [number, setNumber] = useState<number>(0) // 기본값이 0
state 는 props 를 통해 자식 컴포넌트에 전달될 수 있고, 자식 컴포넌트에서도 그 state 를 변경할 수 있는데, 다음과 같은 방법으로 할 수 있다.
.../Home/index.tsx
function Home() {
const [count, setCount] = useState<number>(0)
return (
<div>
<Sample count={count} setCount={setCount} />
</div>
)
}
.../Home/Sample/index.tsx
import React from "react"
interface ISample {
count: number
setCount: (count: number) => void
}
function Sample(props: ISample) {
const { count, setCount } = props
return (
<div>
<button onClick={() => setCount(count + 1)}>increase</button>
{props.count}
</div>
)
}
export default Sample
부모 컴포넌트인 Home 에서 count state 와 그 state의 setter 인 setCount 를 모두 props 로 넘겨주었다.
자식 컴포넌트인 Sample 에서는 해당 Props 를 Interface 로 정의 해주고, 다시 구조분해 할당을 통해 Sample 컴포넌트 내의 변수에 저장하고, 넘겨받은 setter 를 통해 count state 를 증가시키는 call back 함수를 정의해주었다.
하지만 이러한 방법은 좋지 않은데, 이는 state 는 해당 컴포넌트에서만 변경가능하게 하는 것이 좋기 때문이다. 따라서 다른 컴포넌트에서 state 를 관리하게 하기위해 상태관리 라이브러리인 redux나 recoil을 사용한다