TIL. ATOMIC DESIGN

FE_JACOB 👨🏻‍💻·2021년 8월 20일
0

Today I learned

목록 보기
23/30

Atomic

아토믹 디자인을 처음 접했을때는 그래 다 쪼개야해 원자, 분자단위로 다 쪼개야돼
이런 생각으로 접근을 했었다.

아토믹 디자인을 하다보니 나중에는 이게 아토믹이 맞나..? 라는 생각이 들었다.
예를들어 ATOMS, MOLECULES는 잘 쪼갰는데 ORGANISM부분이 굉장히 헷갈렸다.

이번 프로젝트에서 사용하는 form 의 형태가 2가지가 있었는데 admin form(login, signup) 과 schedule form (create, read) 이 있었다.

이 두개는 전혀 다른 형태의 form이 었는데 ORGANISM 폴더에 2개의 file을 만들어서 진행을 했었다. 그때까지만 해도 ORGANISM 은 한군데서만 쓰이는 ATOMS, MOLECULES 을 모아둬도 괜찮구나 라고 생각을 했고 이는 실수였다.

서론은 여기까지 하고 내가 어떻게 ATOMIC DESIGN을 구현했는지 적어본다.

폴더구조

src(folder)
	- components(folder)
          -- Atoms(folder)
              --- index.js
              --- Buttons.js ...
          -- Molecules(folder)
              --- index.js
              --- InputLbel.js ...
          -- Organisms(folder)
              --- index.js
              --- Form.js
              --- Calendar.js ...
	- Pages(folder)
          -- Login ...
            --- index.js
            --- data.js
            --- Templete(folder)
                -index.js

components folder 에는

  • Atoms
  • Molecules
  • Organisms
    이렇게 세 폴더로 나누고 최대한 나눌수있는대로 나눴다.

Atoms folder 에는 가장 작은 단위에 component가 들어갔는데
예를들어

function Button({ bg, children, onClick }) {
  return (
    <ButtonEle onClick={onClick} bg={bg}>
      {children}
    </ButtonEle>
  );
}

const buttonType = bg => {
  switch (bg) {
    case 'admin':
      return css`
        width: 100%;
        padding: 1rem 2rem;
        background-color: #ccc;
        color: #fff;
        font-size: 1rem;
      `;
      break;
    case 'comment':
      return css`
        padding: 0.5rem;
        background-color: rebeccapurple;
        color: #fff;
        font-size: 1rem;
      `;
      break;
  }
  
  
  const ButtonEle = styled.button`
	${({ bg }) => buttonType(bg)}
`

이렇게 구성할때 안에 어떤 내용이 들어올수있게 children 으로 값을 받아주고 button click 시 일어날 event의 이름은 모두 onClick이라는 이름으로 받아준다.
props 로 받는 모든것들이 다 이름이 똑같아야 버튼 컴포넌트를 어디서든 사용가능하다.

또한 버튼마다 배경색, 크기, 글자색 등등 style 요소가 다르기때문에 props로 받고 그 받은 props로 style이 될 수 있게 함수로 return 해준다.

그리고 모든 함수를 import 해올때마다

import Button from '../../Components/Atoms/Button/Button.js'
import Input from '../../Components/Atoms/Input/Input.js'
import Label from '../../Components/Atoms/Label/Label.js'

이렇게 계속 선언을 해줘야하니 같은 directoty 안에 index.js 안에 미리 선언을 해준다.

import Button from './Button';
import Input from './Input';
import Label from './Label';

export { Button, Input, Label };

이렇게 미리 import 를 해주면 사용할때

import {Button, Input, Label } from '../../Components/Atoms'

이렇게만 써주면된다.

사실 이 방법이 좋은 방법인지는 나도 아직 잘 모른다. 난 이게 더 깔끔해보이고 가독성이 좋은 코드를 선호하기 때문에 이렇게 코드를 썼지만 실제 이렇게 썼을때 더 번거롭다고 느끼는 분들이 계실수도 있기때문이다.

다른 MOLECULES, ORGANISMS 도 이렇게 마찬가지로 작성했다.
Form 안에 들어가야할 요소들이 다르다면 children으로 뚫어놓고 값을 Templete단위에서 넣어주면 된다.

이제 Pages 폴더로 들어가보면

index.js 파일과 Templete folder 가 있다.
index.js 에서는 모든 데이터를 다룬다. 모든데이터를 아래로 뿌려주는 형식이기때문에 함수나 Hookd은 index.js 에 위치해있다.
이 파일안에는 Templete를 import 해서 오직 Templete만 rendering 해준다.

 return (
    <Templete
      fetchLogin={checkValue}
      onChange={onChangeUserValue}
      goToSignup={goToSignup}
    />
  );

이제,
Templete 폴더안에 index.js 파일에서는
Atoms, Molecules, Organisms 들이 다 모여있다. 말 그래도 템플릿을만들듯이 조각모음을 하듯이 내가 만들어놓은 단위들로 페이지 자체를 구성하는거다.

function index({ goToSignup, onChange, fetchLogin }) {
  return (
    <Templete>
      <Form fetch={fetchLogin}> // ORGANISMS
        <Container>
          <Span size="h1">LOGIN</Span> //ATOMS
          <AdminInputBox>
            <InputLabel //MOLECULES
              onChange={onChange}
              name="employee_number"
              type="text"
              placeholder="Please enter your employee number"
            >
              Employee Number
            </InputLabel>
            <InputLabel  //MOLECULES
              onChange={onChange}
              name="password"
              type="password"
              placeholder="Please enter your password"
            >
              Password
            </InputLabel>
          </AdminInputBox>
          <Button onClick={goToSignup} bg="admin"> //ATOMS
            GO TO SIGNUP
          </Button>
          <Button bg="admin" fetch={fetchLogin}> //ATOMS
            LOGIN
          </Button>
        </Container>
      </Form>
    </Templete>
  );
}

이렇게 안에서 조각모음을 해주면되는데, ATOMIC DESIGN을 할때 가장 놀랬던건 maping 을 하거나 뭔가가 연결이 되어있으면 안된다는것이다.

흔히하는 말로 '하드코딩'을 하는 식으로 만들어야한다는거다.
처음 이를 접했을때 왜?? 왜 이렇게 하지 ? 라는 생각이 들었는데 Templete중 하나의 조각을 주석처리를 하더라도 페이지에 오류가 안나고 잘 돌아가야한다. 이게 포인트였다.
그래서 모든걸 다 쪼갰던거다.

마무리

Atomic Design을 사용하면 전역 상태관리 툴을 안써도 된다?
위에서 props로 내려주는 depth가 낮다.
Page단위에서 Templete으로만 내려주면 다 작동을 하니, 굳이 전역상태관리 툴을 사용할 필요가 없다고한다.

물론 페이지와 페이지 사이의 의존성이 크다면 전역상태관리툴을 사용하는게 좋을거같다. 하지만 이번프로젝트는 오직 login, signup, calendar 정도만 사용하기 때문에 의존성이 크지않았다.

그리고 지금까지 프로젝트를 했을땐 top to bottom 형식을 사용했다면 이번에는 가장작은 단위의 Atoms 부터 디자인을 하는 bottom to top 형식을 사용하다보니 길을 많이 잃었다.
하지만 전혀 다른 방식의 디자인을 해봤다는것은 큰 경험이었다.

profile
단순히 개발자로서 제게 있었던 일을 적는 공간입니다 ✍🏻

0개의 댓글