[인턴일지] MISE - 3 (컴포넌트, 모듈화)

Sio·2022년 3월 11일
0

글을 적을때마다 느끼는 건데 항상 첫 마디를 어떻게 시작할까가 제일 어려운 것 같아요😂

저번 포스팅에는 회사 프로젝트에 디자인시스템을 적용한 경험을 이야기해보았는데요, 이번에는 디자인 시스템과 연결되어, 특히 '리액트' 개발자라면 꼭 알고 있어야 할 '컴포넌트화' 또는 '모듈화' 개념에 대해서 알아보겠습니다.

컴포넌트화

체리 프로젝트에서 주로 '버튼' 이란 것은 페이지 하단에 위치하거나 모달창 하단에 위치해서 어떤 동작을 마치거나 넘어갈 때 쓰이는데요!
테두리가 있는 화이트 컬러 배경의 이전 버튼, 그레이 컬러 배경의 비활성화 버튼, 체리블루 컬러의 활성화 버튼 3가지로 나누어 지는데요, 아래 사진을 보면 어떤 식으로 쓰이는 지 알 수 있습니다.

버튼들의 공통점은 height와 border radius 정도가 똑같고, 안에 들어가는 텍스트나 너비, 색깔 등은 다릅니다.

물론 스타일링을 할 때 Styled Component를 써도 되고, View나 GlobalStyled 등을 통해서 페이지마다 써도 되지만,

Button.js 라는 하나의 js 파일로 만들어 두면 언제든 import 해서 쓸 수 있지 않을까?

라는 생각을 해볼수 있습니다.

그리고 리액트는 이런 컴포넌트화 방식을 자연스럽게 적용할 수 있도록 만들어진 프레임워크라고 생각합니다! 혹시 컴포넌트화에 대해 아직 잘 모르시겠다고 하면 '리액트 컴포넌트'와 더불어 'props' 라는 개념을 알아보시면 좋을 것 같습니다:)

그럼 어떤 식으로 Button.js 파일을 만드는지, 어떻게 적용하는 지 알아보겠습니다.

const Button = ({
	width,
    height,
    color,
    textColor,
    title,
    borderWidth,
    borderColor,
    borderRadius,
    onPress,
    disabled,
}) => {

	return (
    
    )
}

export default Button;

기본 셋팅은 위와 같습니다. 저는 리액트의 함수형 프로그래밍 방식을 사용했고, 클래스형 프로그래밍 방식과는 조금 다릅니다! 이 부분도 궁금하시면 리액트 함수형 프로그래밍 / 리액트 클래스형 프로그래밍 키워드로 검색해보시길 바랍니다.

({}) 안에 수많은 변수들은 리액트의 props 기술인데 prop으로 받아 온 값들을 적용 할 수 있습니다. 그러면 return 문 안을 어떻게 구성해야 할까요?

일단 버튼이니 react-native에서 제공하는 TouchableOpacity를 사용해보겠습니다.

const Button = ({
	width, //  버튼 너비
    height, // 버튼 높이
    color, // 버튼 색상
    textColor, // 텍스트 색상
    title, // 텍스트 내용
    borderWidth, // 외곽선 두께
    borderColor, // 외곽선 컬러
    borderRadius, // 외곽선 둥글기
    onPress, // 버튼 눌렀을 때 실행 될 콜백함수
    disabled, // 버튼을 비활성화 하는 조건
}) => {

	return (
    	<TouchableOpaicty
        	style ={{
            	width: width || '100%',
          		height: height || 45,
            	backgroundColor: color ? color : 'white',
            	borderWidth: borderWidth || 0,
            	borderColor: borderColor ? borderColor : color,
                borderRadius: borderRadius || 12,
            	justifyContent: 'center',
            	alignItems: 'center',
            }}
            disabled={disabled ? disabled : false}
      		onPress={onPress}
        >
        	<GlobalStyled.Noto4 color={textColor || 'white'}>
            	{title}
        	</GlobalStyled.Noto4>
        
        </TouchableOpacity>
    )
}

export default Button;

논리연산자 / 단축평가

width || '100%' 가 뭐지? 싶은 분들이 있을 것 같습니다.

자바스크립트의 논리연산자(||, &&) / 단축평가의 개념을 아시나요?

  1. ||(논리합) 연산자의 단축평가

||의 경우, 둘 중 하나만 true 이면 true로 평가 되므로, 왼쪽 피연산자가 true이면 바로 왼쪽 값을 반환합니다.

"apple" || "banana" >>> "apple"
false || true >>> true
false || "banana" >>> "banana"

즉, 패턴을 정리해보면 다음과 같습니다.

값 || true >>> 값
값 || false >>> 값
true || 값 >>> true
false || 값 >>> 값
값A || 값B >>> 값A

  1. &&(논리곱) 연산자의 단축평가
    &&의 경우 둘 다 true 여야만 true로 반환되므로, 왼쪽 피연산자가 false이면 바로 false로 평가됩니다. 특히 "왼쪽이 true라면 무조건 오른쪽 값을 반환할 때" 쓸 수 있습니다.

false && "banana" >>> false
"apple" && false >>> false
"apple" && true >>> true

즉, 패턴을 정리해보면 다음과 같습니다.

false && 값 >>> false
true && 값 >>> 값
값 && false >>> false
값 && true >>> true
값A && 값B >>> 값B

그렇다면, width || '100%' 은 무엇일까요?
prop으로

<Button width={50} />

이런 값이 온다고 하면, Button.js 내에서
50 || '100%'
단축평가를 할 것입니다.
50이라는 true 값이 들어 왔으니 width 는 50이 됩니다.
width라는 prop을 안주었다면, false || '100%'로 평가되어, 그냥 너비가 '100%'인 버튼을 반환하겠지요?

그렇다면 아래와 같은 버튼을 생성해봅시다.

import Button from '../../components/Button'; // 예시입니다.

const ButtonTestPage = () => {
	const onPress = () => {
    	// 버튼을 누르면 실행되는 코드
    }
    
	return (
    	<Button 
        	title="완료"
            color={theme.SubBlue}
            onPress={onPress}
        />
    )
}

export default ButtonTestPage;

이런식으로 간단하게 만들 수 있습니다!

응용해서, 두개가 나란히 이어져 있는 버튼과 활성화/비활성화 상태는 어떻게 구분할까요?

<GlobalStyled.ViewRow
	style={{
    	justifyContent: 'space-between',
        height: 'auto',
        width: wp(100) - 48,
    }}
>
    <Button
        width={(wp(100) - 48 - 15) / 2}
        color={theme.White}
        borderWidth={1}
        borderColor={theme.LightGray2}
        title={'이전'}
        textColor={theme.DarkGray1}
        onPress={() => {
           navigation.goBack();
        }}
     />

     <Button
     	width={(wp(100) - 48 - 15) / 2}
        color={활성화조건 ? theme.SubBlue : theme.LightGray2}
        title={'다음'}
        disabled={!(활성화조건)}
        onPress={onPress}
     />
</GlobalStyled.ViewRow>

width를 저렇게 준 이유는 양옆 margin 24*2dp, 가운데 15dp를 빼주고 2로 나누면 버튼 하나의 크기가 나오기 때문입니다😀

간단하게 버튼으로 예시를 들어봤는데, 컴포넌트화 참 쉽죠? prop으로 숫자나 문자열 같은 값 뿐 아니라 함수도 보낼 수 있으니 앞으로 코드를 짤 때 컴포넌트화를 적극적으로 활용하시길 바래요✨

profile
나는 시오

0개의 댓글

관련 채용 정보