본문 바로가기
> 개발/React

[React] Cannot read properties of null (reading "length') 오류 해결하기

by @일리 2023. 3. 3.

2022년 1월 12일 작성

 

프로젝트를 하면서 빈 화면만 나타나는 경우가 있었다. 그 원인은 바로 Cannot read properties of null (reading 'length') 오류다! 이 오류는 구하려는 값이 null이여서 length 를 구할 수 없을 때 발생한다.

 

오류 화면
수많은 오류들...

length 를 활용한 부분이 많아서 관련된 부분을 모두 주석 처리 후 하나씩 주석을 해제하면서 오류가 발생한 부분을 찾았다. 그리고 문제를 해결하기 위해서 && 연산자와 옵셔널 체이닝을 활용했다.

&& 연산자

      <p className="reperesnetTitle">
        {cartProducts[0].price && cartProducts[0].productName} 외&nbsp;
        {cartProducts.length - 1}개의 상품을 주문합니다.
      </p>
      
      <p className="reperesnetTitle">
        {cartProducts[0].price && cartProducts[0].productName} 외&nbsp;
        {cartProducts && cartProducts.length - 1}개의 상품을 주문합니다.
      </p>

 

기존코드가 위에 코드고, 오류를 해결한 코드가 아래에 있는 코드다. 이렇게 && 연산자를 사용하면 cartProducts와 cartPRoducts.length-1 이 모두 true 일 경우 뒤에 값을 보여준다. 따라서 앞에 값이 null, 즉 false 일 때는 뒤에 값이 렌더링되지 않아 오류가 생기지 않는다. 이러한 연산이 가능한 이유는 단축회로평가 논리 덕분이다.

단축평가

일반적으로 표현식의 평가는 왼쪽에서 오른쪽으로 진행된다. 단축평가는 표현식을 평가하는 중 평가 결과가 확정이 되면 나머지 평가 과정을 생략하고 결과를 반환하는 것을 말한다.

논리곱(&&) 연산자

&&연산자일 때

&& 연산자에서는 A && B 가 모두 true 여야 true가 반환되고
하나라도 false가 있으면 false가 반환된다.

 

&& 연산자에서는 모두가 'true'여야 true 값이 반환되기 때문에
왼쪽 값이 true여도 오른쪽 값까지 true인지를 확인해야 한다.


하지만 왼쪽 값이 false라면 오른쪽 값을 보지 않더라도 이미 false가 되는 것이므로 오른쪽 값까지 평가하지 않고 false를 반환한다.

여기서 왼쪽 값이 true일 때 오른쪽 false 값이 반환된 것을 볼 수 있다.


만약 둘 다 'true1' && 'true2'처럼 true 값이라면 두 번째 'true2'가 반환된다. 이는 앞서 말했듯 모든 값이 true여야 하기 때문에 뒤에 있는 true2의 값까지 확인해야하기 때문이다! 이제 왜 &&를 써서 특정 조건일 때 뒤에 값이 보이도록 만들었는지 이해가 간다^ㅇ^

논리합(||) 연산자

|| 연산자에서는 A || B 가 모두 false 여야 false가 반환되고,
하나라도 true 가 있으면 true가 반환된다.

&#124;&#124; 연산자일 때

|| 연산자에서는 여러 식 중 하나만 'true'면 되기 때문에
왼쪽 값이 true라면 오른쪽 값을 보지 않아도 된다.


하지만 왼쪽 값이 false라면 true 값을 찾아 오른쪽 값까지 평가해야 한다.
논리합 연산자의 평가과정은 true 값을 찾아 떠나는 여정이다 ~(@_@)~

 

+ 옵셔널 체이닝

 

추가적으로 && 연산자 대신 옵셔널 체이닝을 사용할 수 있다. 옵셔널 체이닝은 && 연산자보다 나중에 도입된 개념이다. && 연산자를 사용할 경우 코드가 길어져 보기 좋지 않은데, 옵셔널 체이닝을 사용하면 깔끔하게 코드를 작성할 수 있다.

 

위에 있던 코드를 옵셔널 체이닝으로 수정한다면,

   <p className="reperesnetTitle">
            {cartProducts[0].price && cartProducts[0].productName} 외&nbsp;
            {cartProducts?.length - 1}개의 상품을 주문합니다.
          </p>

 

이렇게 수정할 수 있다. cartProducts가 있으면 cartProducts.length-1을 표시하라는 뜻이다. 참고로 옵셔널 체이닝을 많이 사용하면 나중에 디버깅이 어렵다고 하니 남용하면 안된다. 관련 내용은 하단 링크 참고하길 바란다.

 

https://ko.javascript.info/optional-chaining

댓글