Skip to content

개발자 메뉴얼 | 기술 스택

Suyeon edited this page Dec 5, 2023 · 2 revisions

📄 반응형 디자인 기기별 테스트 툴

다들 공감하시겠지만 반응형 디자인을 적용할 때 매번 화면 기기에 따른 해상도를 변경하며 확인해야하기에 불편함을 느꼈던 적이 많았습니다.

스크린샷 2023-11-07 오전 8 49 10

가끔은 하나의 디바이스 해상도만 가지고 UI 개발을 하다가 다른 디바이스 해상도를 확인하면 원래는 멀쩡했던 디자인이 망가진 모습을 발견하기도 합니다🥲🥲.

이런 불편함과 문제를 해결하기위해 responsively라는 툴을 저희 프로젝트에 도입하려고 합니다.

Responsively?

Responsively라는 툴은 여러가지 기기 해상도에서 웹 페이지를 한 눈에 확인할 수 있도록 도와주는 툴입니다.

스크린샷 2023-11-07 오전 8 57 28

하나의 화면에서 다양한 기기의 해상도에 맞게 웹페이지를 확인할 수 있습니다.

스크린샷 2023-11-07 오전 8 59 11

다양한 OS에서 무료로 사용할 수 있으며 GitHub star가 2만개가 넘어갈 정도로 많은 관심을 받고있는 툴입니다.

Responsively 사용법

Responsively의 사용법은 정말 간단합니다! 쉽게 생각해서 그냥 크롬, 사파리 처럼 브라우저를 사용하는데 거기에 디자인 적용에 특화된 기능들을 제공한다고 생각하면 될 것같습니다.

하나의 페이지에서의 동작을 모든 페이지가 공유

2023-11-07.9.05.47.mov

하나의 화면에서 수행한 동작들이 실시간으로 모든 화면과 공유가 되며 이를 통해 모든 기기 해상도에서 동작을 쉽게 확인할 수 있습니다.

네이버와 같은 정적 디자인에서는 공유가 되지 않는 것 같습니다. 하지만 저희 프로젝트에서는 동작하는 것을 확인했습니다!


사용자 히스토리 데이터 삭제

스크린샷 2023-11-07 오전 9 10 23

주소 입력창 오른쪽에 위치한 3개의 버튼을 통해 사용자 히스토리 파일을 삭제할 수 있습니다. 각각 스토리지, 쿠키, 캐쉬 삭제 기능을 제공합니다.


Inspect Element 및 dev tools 제공

크롬과 동일하게 요소 검사와 개발 도구를 제공합니다. 사용 방법은 아래의 사진을 통해 알 수 있습니다.

스크린샷 2023-11-07 오전 9 16 11 스크린샷 2023-11-07 오전 9 18 23 스크린샷 2023-11-07 오전 9 14 14

다양한 해상도 추가

스크린샷 2023-11-07 오전 9 22 13

프로젝트를 확인하고 싶은 해상도를 이미 만들어진 프로필을 통해 선택하여 추가하거나 해상도를 직접 커스텀이 가능합니다.

여러 프로젝트를 진행하고 있는데 프로젝트마다 원하는 해상도가 다르다면 Suites를 미리 등록해두어 바로바로 변경이 가능합니다.

스크린샷 2023-11-07 오전 9 23 27 스크린샷 2023-11-07 오전 9 23 45

한번에 여러 해상도 화면 캡처

여러 해상도 화면을 한번에 캡처하는 기능을 제공합니다. 아래 사진의 버튼을 클릭하면 현재 사용자가 선택한 해상도 개수에 맞게 모든 화면이 캡처되어 저장됩니다. 개인적으로는 UI 개발 완료 후 PR을 남길 때 OS에서 제공하는 캡처를 사용해 전체 화면을 캡처하거나 Responsively에 제공하는 캡처를 통해 이미지를 같이 남기면 더 빠른 확인이 가능할 것 같다고 생각합니다!

스크린샷 2023-11-07 오전 9 26 59 스크린샷 2023-11-07 오전 9 29 39

📄 Context API 를 사용하는 이유

이전 프로젝트인 니르바나의 기술 스택을 정할 때 상태관리 라이브러리로 Recoil 을 도입했다. 나도 Recoil 을 도입하는 데 이견이 없었지만 무언가를 알고 사용하자고 한 것은 아니었다. 팀원들이 사용해보고 싶어했고, 나도 무언가를 하나 더 알아두면 무조건 좋을 것이라고 생각했다.

그렇다면 다른 라이브러리 도입에 있어선 무언가 달랐을까? 답은 No 였다. Recoil 과 비슷하게 다른 라이브러리들도 의견 교환 없이 바로바로 선정되었고, 프로젝트가 끝나고 보니 해당 기술들을 적재적소에 활용했다는 자신이 없었다.

그래서 이번 프로젝트에선 기술 하나를 새로 도입할 때 왜 우리가 해당 기술을 사용해야 하는가? 를 간단히라도 짚고 사용하는 것이 작은 목표가 되었다.

상태관리 라이브러리

우선 팀원들끼리의 회의가 있었다. 지난 프로젝트에서 사용한 상태 관리 라이브러리는 무엇이며 어떤 점이 좋았는지 등에 대해 얘기를 나눴다.

사용한 라이브러리는 달랐지만 전역 상태 관리가 필요한 곳은 드물다. 라는 의견은 공통적이었다. 그래서 이번엔 상태 관리 라이브러리를 사용하는 대신 react-queryContext API 를 사용하기로 했다. 다음과 같은 이유에서였다.

  1. 기본이 되는 Context API

    멘토님과 커피챗을 진행하며 상태 관리에 대한 이야기가 나왔다. 상태 관리 라이브러리는 내부적으로 Context API 를 사용하기 때문에 그 원리를 잘 이해할 필요가 있다고 하셨다.

    Context API 에 대한 이해도가 낮은 상태에서 다른 상태 관리를 이해하려고 해도 잘 안될 것 같아 이번 기회에 Context API 를 사용하며 익혀보기로 했다.

  2. prop drilling 해결

    전역적으로 사용할 상태가 드물긴 해도, 특정 데이터가 필요하지 않은 컴포넌트에 데이터를 내려보내주는 일은 꽤 불편한 일이다.

    다른 패키지를 추가로 설치하지 않으면서도 필요한 컴포넌트만 컨텍스트를 구독하는 방식으로 Prop drilling 문제를 해결할 수 있어 Context API 가 적합하다고 생각했다.

Context API 가 필요한 상황

상태 관리 라이브러리의 필요성은 리액트로 프로젝트를 진행해본 사람이라면 쉽게 알 수 있다. prop 을 저 멀리까지 넘겨주기 위해 사용하지도 않는 컴포넌트에게까지 prop 을 전달해주는 현상이나, 자식의 자식의 자식의…. 컴포넌트에게 해당 prop 을 모두 전달하고 싶은 경우가 더러 있다.

아래의 경우 prop 으로 받는 level 컴포넌트에 따라 각각 다른 크기의 Heading 을 반환한다

<Section>
  <Heading level={3}>About</Heading>
  <Heading level={3}>Photos</Heading>
  <Heading level={3}>Videos</Heading>
</Section>

이 경우 level 을 각각 컴포넌트에 전달해야한다는 번거로움이 있는데, 그러기 보단 Section 에 level 을 전달해주면 Heading 에 전달하는 방식이 더 편할 것이다.

<Section level={3}>
  <Heading>About</Heading>
  <Heading>Photos</Heading>
  <Heading>Videos</Heading>
</Section>

그런데 이 경우 어떻게 Heading 컴포넌트가 가장 가까운 조상 컴포넌트 Section 의 level 을 알 수 있을까? 이 경우 자식 컴포넌트가 데이터를 요청하는 기능이 필요할 것이다.

이 과정은 props 만으로는 이뤄질 수 없기 때문에 Context 가 필요하다.

Context 의 3단계

  • Create

    Context 를 생성한다.

  • Use

    Context 를 사용한다.

  • Provide

    등록한 데이터를 제공한다.

Untitled

컨텍스트는 다음 그림과 같이 자식 컴포넌트에 데이터를 전달할 수도 있고, 더 아래에 있는 특정 컴포넌트에만 데이터를 등록할 수도 있다.

Untitled

사용방법

Create

createContext 메서드를 사용하여 전역적으로 사용할 상태를 추가한다.

파라미터의 값으론 초기 데이터 값이 들어가는데, 위 예제에선 level 을 전달하고 있으므로 1 이라는 숫자를 defaultValue 로 주었다.

// state/level.js

import { createContext } from 'react';

export const LevelContext = createContext(1);

Use

useContext 메서드를 사용하여 생성한 Context 를 사용할 수 있다.

import { createContext } from 'react';
import { LevelContext } from 'state/level.js';

기존의 Heading 컴포넌트는 아래와 같이 prop 으로 전달 받는 형식으로 데이터를 가져왔다.

const Heading = ({level, children}) => {
	// ...
}

이제 Context API 를 사용함으로써 다음과 같이 prop을 줄일 수 있다.

import { createContext } from 'react';
import { LevelContext } from 'state/level.js';

const Heading = ({ children }) => {
	const level = useContext(LevelContext);
}

Provider

생성한 Context 를 제공해주기 위해선 제공해주려는 컴포넌트에서 하위로 내려줘야 한다.

Context.Provider 를 사용하여 컴포넌트를 감싸고, 넘겨주고자 하는 값을 value 로 넘겨준다.

import { LevelContext } from 'state/level.js';

const Section = ({level, children}) => {
	return (
		<LevelContext.Provider value={level}>
			{children}
		</LevelContext.Provider>
	)
}

Context API 단점

React 공식 문서에서 Context API 사용 방법을 읽어본 결과 꽤 간결하고 쉬운 문법을 가지고 있다는 것을 알게 되었다. 그런데 왜 사람들은 다른 상태 관리 라이브러리를 도입하려고 하는 것일까?

리렌더링의 문제

현재 나온 상태 관리 라이브러리는 어떤 상태가 변경되면 해당 상태를 참고하고 있는 컴포넌트만 업데이트 시킨다. 하지만 Context API 는 어떤 데이터가 업데이트 되면, 해당 데이터를 사용하는 컴포넌트를 포함하여 해당 컨텍스트를 구독하는 모든 컴포넌트가 업데이트 된다.

이에 따라 적절하게 Context Provider 의 범위를 설정하고 여러개의 Context 로 나눔으로써 해결할 수 있긴 하나, 이 역시 코드의 복잡성이 증가하는 문제로 번질 우려가 있다.

수많은 Provider 생성의 문제

리렌더링 문제를 해결하기 위해 여러개의 Context 로 나누면 코드의 복잡성이 증가한다. Context 단위가 증가할 수록 수많은 Provider 를 작성하게 될 수 있다.

더불어 이렇게 많은 Context 를 생성하게 될 시 Context 를 작성하고 사용하는 것이 편리함의 범주를 벗어나기 때문에 Context API 보다 보기 쉽고 편리한 상태관리를 찾는 것이라 판단을 내렸다.