React Study (2)- Atomic Design / Props & State

박다현·2022년 3월 9일
2

React Study

목록 보기
2/3

Atomic Design

Atomic Design 은 가장 작은 단위(Atom)로 부터 컴포넌트를 작성하고, 이러한 컴포넌트들을 결합하여 더 큰 컴포넌트(Molecules, Organisms)를 구성하는 디자인 패턴이다.

  • Atoms : 가장 작은 단위의 컴포넌트이다. 스타일을 가질 수 있다.
  • Molecules: Atoms 가 결합된 컴포넌트이다.
  • Organisms: Molecules 가 결합한 컴포넌트이다.
  • Templates: Organisms 이 결합하여, Page를 위한 Template 으로 활용될 수 있다.
  • Pages: Templates 를 채운, 실제로 보여지는 Page 이다.

Atomic Design 과 폴더구조

Atomic Design 을 폴더 구조에 어떻게 적용할 것인지는 여러가지 방법론이 있다. Atomic 구조 그대로 components 폴더 하위에 atoms 부터 pages 까지 존재하며, 가장 작은 단위를 모두 atoms 에 존재하게 하면서, 이를 조합하게 할 수 있다.

하지만 이럴 경우에, atoms 의 파일들이 많이 쌓일 수 있다. 따라서 특정 organsims 에만 쓰이거나 특정 page 에 쓰이는 컴포넌트는 해당 organsims 또는 page 또는 molecules 하위에 존재하게 하고, 공통으로 쓰이는 컴포넌트만 atoms에 존재하게 하는 방법이 있다.

--components
   --atoms
   --molecules
   --organisms
   --templates

--pages
   --PageA
   --PageB
...

Props

부모컴포넌트가 자식 컴포넌트에게 주는 값. 자식 컴포넌트에서는 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

state 는 컴포넌트 자기 자신이 가지고 있는 값이고, 동적인 데이터를 다룰 때 사용한다. setState 함수를 통해서만 변경한다.

useState

React 기본 함수, 이를 이용하면 컴포넌트에서 상태를 관리할 수 있다. 이 함수에 타입을 지정하고 default 값을 인자로 주어 호출하면, array 를 반환하는데, 첫번째 원소는 state 가 저장되는 변수이며, 두번째 원소는 그 변수를 변경할 수 있는 setter 이다.

const [number, setNumber] = useState<number>(0) // 기본값이 0

Props & State Example Code

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을 사용한다

0개의 댓글