본문으로 건너뛰기

23.07.07

오늘 한 일

  • Gloddy
    • PR 코드 리뷰
    • ConfirmModal 컴포넌트 구현
  • Rust 3장, 4장 소유권 조금 읽음

하루 요약

  • 12:00 ~ 17:30 카공
  • 19:30 ~ 23:00 집공

Gloddy

코드 리뷰

image

코드 리뷰하는데 꽤 시간을 많이 썼다. 코드를 보니 컨벤션을 맞춰봐야 할 것들이 많아서 꼼꼼하게 리뷰 남겼다. 그리고 직접 회의를 통해 어느정도 컨벤션을 맞출 수 있었다.

새로 알게 된 것

@types 폴더의 의미

사실, 나도 이전 프로젝트에서 @types 폴더를 별 생각 없이 사용했었다. 그냥 다른 프로젝트들도 이렇게 쓰니까 따라 써야지 하고 사용했었다.

그런데, 이번에 코드 리뷰를 하면서 @types 폴더의 의미를 알게 되었다.

예를 들어, 리액트 같은 라이브러리도 react만 설치하면 타입을 사용할 수 없다. 리액트의 타입을 사용하려면 @types/react를 설치해야 한다. 그러면 react 라이브러리의 타입을 사용할 수 있다.

@types/reactDefinitelyTyped에서 관리하는 타입이다. 이 DefinitelyTyped는 타입스크립트에서 사용할 수 있는 타입들을 모아놓은 저장소이다.

그런데, DefinitelyTyped에는 모든 라이브러리의 타입이 다 있지는 않다. 그래서, DefinitelyTyped에 없는 라이브러리의 타입을 사용하려면 직접 타입을 만들어야 한다.

그래서, @types 폴더를 만들고 그 안에 직접 타입을 만들어서 사용하는 것이다.

모듈 타입을 선언한 d.ts 파일을 관리하기 위한 폴더가 바로 @types 폴더이다.

그럼, 일반 타입들은 어디에 선언해야 하나?

일반 타입들은 types 폴더에 선언하기로 했다. 해당 고민에 대해 PR 코멘트를 남겨 이야기를 나눴다.

ConfirmModal 컴포넌트 구현

Compound Component 패턴을 적용해보고 싶었는데, 오히려 사용자 입장에서 불편할 것 같다.

<ConfirmModal isModalOpen={isModalOpen}>
<ConfirmModal.Content
okButtonProps={{
text: '버튼1'
}}
cancleButtonProps={{
text: '버튼2'
}}
>
// 컨텐츠
</ConfirmModal.Content>
<ConfirmModal>

이런 식으로 사용해야 하는데, ConfirmModal에 들어가는 버튼을 저렇게 props로 받게 되면 사용자 입장에서는 불편할 것 같다.

그래서 내일 다시 리팩토링 하려 한다..

구현 코드
import { forwardRef } from 'react';
import ModalWrapper from './ModalWrapper';
import Button, { type ButtonProps } from '@/components/common/Button';

interface ConfirmModalProps {
isModalOpen: boolean;
forwardedRef?: React.Ref<HTMLDivElement>;
children?: React.ReactNode;
}

function ConfirmModal({ isModalOpen, forwardedRef, children }: ConfirmModalProps) {
if (!isModalOpen) return null;

return (
<>
<ModalWrapper />
<div ref={forwardedRef} className='absolute z-10 w-300 rounded-10 bg-white px-16 pb-15 pt-30'>
{children}
</div>
</>
);
}

interface ModalContentProps {
okButtonProps: ButtonProps;
cancelButtonProps: ButtonProps;
children?: React.ReactNode;
}

function ModalContent({ okButtonProps, cancelButtonProps, children }: ModalContentProps) {
return (
<div className='p-25'>
{children}
<div className='mt-25 flex flex-col gap-8'>
<Button {...okButtonProps} />
<Button {...cancelButtonProps} />
</div>
</div>
);
}

const confirmModalRef = forwardRef<HTMLDivElement, ConfirmModalProps>(
(props, ref): JSX.Element => (
<ConfirmModal {...props} forwardedRef={ref}>
{props.children}
</ConfirmModal>
)
);

export default Object.assign(confirmModalRef, {
Content: ModalContent,
});

forwardRef 사용 시 Compound Component 패턴 적용하는 법

원래는 ConfirmModal.Content = ModalContent 이런 식으로 사용하려고 했는데, forwardRef를 사용하면 ConfirmModal.Content를 찾을 수 없다고 에러가 뜬다.

stackoverflow를 보니 forwardRef를 사용할 때 Object.assign을 사용해서 Compound Component 패턴을 적용하는 방법이 있었다.

const confirmModalRef = forwardRef<HTMLDivElement, ConfirmModalProps>(
(props, ref): JSX.Element => (
<ConfirmModal {...props} forwardedRef={ref}>
{props.children}
</ConfirmModal>
)
);

Rust

fibo 함수를 구현해보았다.

fn main() {
for num in 1..10 {
println!("{}", fibo(num));
}
}

fn fibo(n: u32) -> u32 {
if n == 1 {
return 1;
} else if n == 2 {
return 1;
} else {
return fibo(n - 1) + fibo(n - 2);
}
}

아직까지는 기본 문법만 공부해서 할만 하다. 오늘 4장 소유권을 조금 읽어보았는데 메모리 얘기 나오고 힙, 스택 관련 얘기도 나오는 거 보니 이제부터 어려워 질 것 같다.


내일 할 일

  • 프로그라피 세션
  • Gloddy create-meeting 페이지 리팩토링