Published on

팝업 컴포넌트 만들어보기

4분

이전 글에서 컴포넌트를 직접 만들어보겠다고 했었는데, 먼저 팝업 컴포넌트를 먼저 만들어보기로 했다.

그냥 팝업만 만들면 밋밋(?) 할 것 같아서 Form과 같이 작업했다.

이메일과 비밀번호를 입력받고, 비밀번호는 8자 이상 20자 이하로 지정했다.

const Toast = ({ isError }: ErrorProps) => {
  return (
    <Notification error={isError ? 'true' : 'false'}>
      <p>{isError ? 'Fail' : 'Success'}</p>
    </Notification>
  )
}

const Notification = styled.section<{ error: string }>`
  ...
  animation: ${FadeIn} 4s linear forwards;
  background-color: ${({ error }) => (error === 'true' ? '#E74C3C' : '#07bc0c')};
`

Notification에 error props를 전달해서 조건에 따라 background-color를 달리 나타내도록 설정해줬다.

마주쳤던 오류와 해결

처음에 error의 type을 boolean으로 설정했었는데

...
    // true, false 삭제
    <Notification error={isError}>
      <p>{isError ? 'Fail' : 'Success'}</p>
    </Notification>

...
  background-color: ${({ error }) => (error ? '#E74C3C' : '#07bc0c')};
Warning: Received `true` for a non-boolean attribute `error`.
If you want to write it to the DOM, pass a string instead: error="true" or error={value.toString()}.

background-color는 의도대로 바뀌기는 했지만 폼 조건에 맞게 값을 입력해도 위와 같은 오류가 나왔다.

즉, error를 string 값으로 바꾸라는 말 같은데 error를 true, false 도 아니고 'true', 'false' 로 설정하는 게 싫었다.

그래서 자료를 더 찾던 중에 styled-components v5.1 부터는 props 앞에 prefix($) 를 붙이는 기능이 추가되었다고 한다.

const Comp = styled.div`
  color: ${(props) => props.$draggable || 'black'};
`

render(
  <Comp $draggable="red" draggable="true">
    Drag me!
  </Comp>
)

문서를 보면 스타일이 지정된 element가 DOM요소로 렌더링 되는 것을 일시적으로 방지할 수 있다고 한다.

error$error로 바꿔주니 새로고침하고 다시 입력했을 때 위에 언급했던 오류가 더 이상 나오지 않았다.

...

    <Notification $error={isError}>
      <p>{isError ? 'Fail' : 'Success'}</p>
    </Notification>

...
  background-color: ${({ $error }) => ($error ? '#E74C3C' : '#07bc0c')};

이틀동안 작업하면서 토스트 컴포넌트 제작 자체는 어렵진 않았지만 이걸 Form과 같이 작업하다보니 시간이 좀 더 걸린 것 같다.

그리고 styled-components를 써오면서 전혀 겪어보지 못했던 오류를 해결하면서 얻은 보람도 있어서 내 나름대로 좋은 경험이었다.

하지만, 만들어놓은 걸 실제 프로젝트에 적용할려면 더 많은 수정을 거쳐야 할 것이다..

다음 글에서는 글 작성 취소 버튼을 클릭했을 때 나타나는 모달을 만들어볼까 하는데, 디자인은 최대한 비슷하게 가볼려고 한다.

Reference

https://styled-components.com/docs/api#transient-props