• Warning Received `true` for non-boolean attribute :: 마이구미
    React 2020. 11. 6. 22:10
    반응형
    이 글은 styled-components 에서 발생할 수 있는 Warning 을 다룬다.
    "non-boolean attribute" 에 관한 Warning 을 경험했다면, 이 글이 충분히 도움이 될 것이다.
    원인과 해결방안 그리고 실제 Github 에 등록된 이슈와 버전 히스토리을 살펴본다.

     

    styled-components 를 사용하다보면, 다음과 같은 Warning 을 경험할 수도 있다.

     

    Warning: Received `true` for a non-boolean attribute `{속성}`.
    If you want to write it to the DOM, pass a string instead: {속성}=“true” or {속성}={value.toString()}.

     

    사실 Warning 내용만으로는 한번에 의미를 파악하기 힘들다.

    직역하면 불리언 타입이 아닌 속성에 true 값을 받아들였다는 것이라, 값을 string 형태("true") 로 제공하라고 말한다.

     

    실제로 예제를 통해 에러를 확인해보자.

     

     

    const Image = styled.img``;
    const Div1 = styled.div`
      display: none;
      ${({ on }) =>
        on &&
        css`
          display: block;
        `}
    `;
    const Div2 = styled.div``;
    
    export default function App() {
      return (
        <div className="App">
          <Image alt={true} />
          <Div1 on={true}>Div1</Div1>
          <Div2 abc={true}>Div2</Div2>
        </div>
      );
    }

     

    예제 코드에서는 img 태그에 alt 속성이 존재하고, 두개의 div 태그에는 on 속성과 abc 속성이 따로 존재한다.

    참고로 on 속성은 display 의 block 과 none 처리를 위한 prop 용도로 사용된다.

    세가지 속성 모두 boolean 값을 넘겨주고 있고, 콘솔에는 언급했던 Warning 2개가 출력되는 상황이다.

     

    1. 왜 Warning 이 출력되는가?
    2. 3개의 요소 중에 Warning 을 출력하는 요소 2개는 무엇인가?
    3. 왜 2개의 Warning 이 출력되는가?

    질문들의 답을 풀어가본다.

    우선, 다음 내용을 인지하고 넘어가야한다.

     

    기본적으로 img 태그의 속성에는 src, alt, width, height 등을 가지고 있다.
    이러한 속성들을 우리는 HTML 표준 속성이라고 부를 수 있다.
    그 외에도 다양한 태그에서 가지는 표준 속성들이 있다. (https://developer.mozilla.org/ko/docs/Web/HTML/Attributes)
    표준 속성의 반대되는 것을 나타내는 것은 비표준 속성이라고 부를 수 있다.

     

    다시 예제로 넘어가서, 우선 img 태그를 확인해보자.

    예제의 표준 속성인 alt 은 string 타입으로 전달해야하는 속성이다.

    하지만 우리는 boolean 값으로 전달했기 때문에, non-boolean attribute 관련 경고 문구가 출력되게 된다.

    우리는 첫번째 질문인 "왜 Warning 이 출력되는가?" 에 대한 답을 알 수 있다.

     

    하지만 2번 질문을 아직 풀지 못했다.

    각각을 주석처리해가면서 확인해보면, Warning 의 원인이 되는 요소를 찾을 수 있다.

     

    <Image alt={alt} />
    <Div1 on={true}>Div1</Div1>
    // <Div2 abc={true}>Div2</Div2>

     

    결국 <Image> 와 <Div1> 가 Warning 의 원인인 것을 파악할 수 있다.

    그리고 우리는 on 과 abc 속성 모두 비표준 속성이라는 것을 알 수 있다.

    그렇다면 두가지 모두 Warning 을 출력해야하지만, abc 속성은 Warning 을 출력하지않는다.

    4번 질문을 추가하겠다.

     

    4. 왜 on 속성은 Warning 이고, abc 속성은 Warning 이 아닌가?

     

    어찌됐든 1번, 2번 질문에 대한 답은 찾아냈다.

     

    3번, 4번 질문의 답을 하기 위해서는 조금 더 들여다보아야한다.

    주석처리되어있는 <Div3> 를 확인해보자.

     

    <Div3 abc={true} test="123" on="23">Div3</Div3>

     

    styled-components 로 만들어진 div 태그에는 abc, test, on 속성이 존재한다.

    그리고 실제 렌더링된 코드를 보면 다음과 같다.

     

     

    on 속성의 값만 노출되고 있는 모습을 볼 수 있다.

    그 이유는 공식 문서의 내용을 참고할 수 있다. (https://styled-components.com/docs/basics#passed-props)

     

    Note how the inputColor prop is not passed to the DOM, but type and defaultValue are. That is styled-components being smart enough to filter non-standard attributes automatically for you.

     

    즉, 실제 DOM 엘리먼트에 전달하기 전에, styled-components 내부에서 비표준 속성을 자동으로 필터링한다는 것이다.

    추측할 수 있는건 abc, test 속성은 필터링 대상으로 노출되지 않는다는 것이다.

    그렇다면, 필터링 기준은 무엇인가?

     

    v3 - https://github.com/styled-components/styled-components/blob/1fd1cc609da9eaa1aaad9e8a7963d6cc9b58fc9c/src/utils/validAttr.js#L15

    v4, v5 - https://github.com/emotion-js/emotion/blob/master/packages/is-prop-valid/src/props.js

     

    현재 버전에서는 emotion 의 모듈을 사용하고 있다.

    소스를 확인해보면 on 속성이 포함되어있는 것을 볼 수 있다.

    주석을 보아, amp html 을 위해 on 속성이 포함되고 있는것으로 추정된다.

    결과적으로 이 기준에 부합하지 않는 abc, test 속성은 자동으로 필터링되어진 것이다.

    그리고 기준에 부합하는 on 속성은 DOM 엘리먼트에 전달되어 요소의 속성으로 선언되었다.

    이것이 4번 질문에 대한 답이 된다.

    그대로 3번 질문에 대한 답으로 alt, on 속성은 DOM 엘리먼트에 전달될 수 있는 대상으로 선언되었지만, non-boolean attribute 로 Warning 을 출력한 것이다.

     

    이처럼 필터링 기준을 우리가 생각하는 비표준 속성도 포함될 수 있기 때문에, 혼란의 여지가 있어보인다.

    그래도 최근에는 이를 위한 새로운 기능이 추가되었다. (아래에서 언급)


    전체적인 히스토리를 파악해보면 다음과 같다.

    전부 연관된 내용이라 순서대로 읽으면 좋을 것이다.

     

    이전부터 관련된 이슈를 최근까지 고민하던 것으로 추정된다.

    https://github.com/styled-components/styled-components/issues/1198

     

    이러한 필터링 로직을 걷어내기 위해, sc 라는 객체형태의 prop 을 제안하기도 했다.

    객체형태로 전달함으로써, DOM 요소의 속성에 영향을 끼치지 않는 방식을 고안한것으로 보인다.

    하지만 완전히 새로운 형태로써, 기존 패러다임과 많이 달라 더 큰 혼란을 줄 것이라 판단하여 채택되지 않은 듯하다.

    https://github.com/styled-components/styled-components/pull/1682

     

    그러다가 최근 5.1 버전에서는 새로운 기능이 추가되었다.

    prefix 로 "$" 를 사용하게 되면, props 가 실제 DOM 요소에 전달되는 것을 막는다.

    https://github.com/styled-components/styled-components/pull/2093

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

     

    잘못된 점이 있다면, 댓글로 남겨주시면 감사하겠습니다.

    반응형

    댓글

Designed by Tistory.