WIL 04, 항해 4주차 이야기

Edwin·2023년 3월 13일

항해99 4주자 이야기

01 이번주 질문 : State, Props, 리렌더링 발생 조건

props와 state

리액트 공식홈페이지에서 말하는 state란 리액트 프로젝트에서 useState를 통해 선언된 하나의 객체이다. 물론 리액트에서는 props 라는 이름의 객체도 존재한다. props란 변경될 수 없는 값으로 상위컴포넌트의 무언가를 하위컴포넌트에 전달해줄 때 사용된다. 반면에 state 객체는 변경이 가능한 형태이며, 이를 통해 input 태그에서 입력받은 내용을 저장하거나, 또는 상태에 따라서 뷰 부분을 제어할 수 있다. 상태 변경은 useState HOOK을 선언했을 때 함께 생성되는 setState를 통해서 변경할 수 있다.

리렌더링의 발생 조건

리액트에서는 위와 같이 props로 전달된 값이 업데이트 되거나, state의 상태가 변경되면 리렌더링을 진행하며, 변경된 내용을 DOM에 반영시킨다. 아래에서 어떠한 경우에 리렌더링이 진행되는지 살펴보자.

  1. state 변경이 있을 때
  2. 새로운 props 또는 기존의 props의 값이 업데이트 되었을 때
  3. 부모 컴포넌트가 렌더링 될 때

총 4개의 경우에 대해서 리렌더링이 발생된다. 그런데 여기서 생각할 주제가 있다. 바로 잦은 리렌더링은 사용자경험을 저하시킨다는 것이며, 제공주로 하여금 높은 비용을 부담준다는 점이다. 바로 이 부분에서 함께 다루어야 하는 주제가 있는데, 바로 렌더링 최적화이다.

렌더링 최적화

바로 이때 등장하는 3총사가 REACT.memo, useCallback, useMemo 이다. 관련된 내용은 아래에 간단하게 정리했지만, 추가적인 학습이 요구된다.

02 이번주의 씨름 가운데 한가지

이번주 과제 중에 하나는 input태그로 숫자를 입력했을 때, 단위에 따라서 콤마(,)를 넣어주는 것이었다. 이를 설정할 때, 속성을 숫자로 하면 되지만, 처음부터 정규식으로 숫자가 아니면 입력을 받지 않도록 하는 방법도 있었다.

  • replace(/[^0-9]/g, "") : 입력된 값이 숫자가 아니면 빈칸으로 변경하는 것이다.
  • replace(/[^\d]/g, "") : d는 숫자를 의미하는 정규식 문법이다. 이렇게 기록할 수도 있다.

replace(/(\d)(?=(?:\d{3})+(?!\d))/g, "$1,");

입력된 내용이 숫자여야만, 주어진 문제를 해결할 수 있다. 그래서 선언된 내용이 위의 정규식표현이다. 도대체 이게 무슨 해괴망측한 표현인지 알 수 없다. 이를 해결하기 위해서 2시간은 가만히 바라만 보고 있었던 것 같다. 그리고 결국에는 이해해 냈다.

먼저 위의 코드의 replace 부분을 독해하면 다음과 같다.

  • / ... /g : 정규식표현
  • "$1," : 정규식에서 만들어진 그룹마다 콤마(,)를 더해서 반환해 줄 것이다.

그리고 이어지는 정규식에 대해서 독해해 보자.

  • (\d) : 정규식에서 (소괄호)는 그룹을 형성하는 것을 의미한다. 그리고 형성된 그룹의 결과로, replace는 동작하여 그룹마다 콤마(,)를 생성해 주는 것이다.
  • (?=(?:\d{3})+(?!\d)) : 그리고 이 부분이 문제이다.

(?=(?:\d{3})+(?!\d))

먼저는 전방탐색x(?=y)이다. x다음에 y가 조재하면 x를 반환한다.

  • (\d) 다음에
  • (?=(?:\d{3})) : 하나의 숫자 다음에 연속되는 3개의 숫자가 존재하면, 전방에 있는 x((\d))를 그룹으로 생성한다는 의미이다. 그렇다면 뒤에 있는 y는 (소괄호) 안에 있는데 그룹을 생성해줄까? 그렇지 않다. (?:) 소괄호 안에 ?:는 해당 내용을 묶기는 했지만, 그룹으로 생성하지 않음을 선언하기 때문이다. 이 결과 1234 이라는 숫자가 입력되면 (1) 이 그룹으로 생성되는 것이다.
  • 그런데 이 y((?=(?:\d{3})+(?!\d))는 포함된 내용이 더 많다.

다음으로는 부정전방탐색(x(?!y))이다. x뒤에 y가 없으면 x를 반환하는 것이다. 그렇다면 위의 코드를 읽어보자.

  • (?:\d{3})+(?!\d) : 연속되는 숫자 3개 뒤에 숫자가 존재하지 않으면 이다. 그렇다면 x를 반환하는 것이다. 그렇다면 아래에서 각각의 예를 살펴보자.

1234 를 사용자가 입력했다고 하자.

  • 1 234 가 먼저 나눠질 것인데, 보면 연속되는 숫자 3개(234) 뒤에 입력된 내용 뒤에 숫자가 없기 때문에 (1)?=(?:234)가 생성될 것이고 해당 내용에 따라서 1,234 가 반환된다.

12345 를 사용자가 입력했다고 하자.

  • 1 (2) (?:345) 가 만들어질이고, 그룹에는 (2)가 등록되고 결과에 따라서 12, 234 가 반환된다.

1234567 를 사용자가 입력했다고 하자.

  • 123 (4) (?:567) 가 만들어질 것이고, 그룹에는 (4)가 등록되고 결과에 따라서 1234,567 이 반환될 것이다.

그런데 여기에 / ... /g 가 있었음을 기억해야 한다.

정규식은 해당 조건이 있을 때마다 내용을 반복하며 실행한다.
1234,567 에서 정규식은 한 번도 발동한다.

  • 숫자가 아닌 콤마(,) 앞에서 조건에 부합하는 내용을 찾은 것이다.
  • (1) (?:234) 의 결과에 따라서 그룹에는 (1) 또 추가적으로 등록되고 결과로 1,23 4,567 이 반환되는 것이다.

1234567890 를 사용자가 입력했다면,

  • 123456 (7) 890 : 123456 7, 890
  • 조건에부합하는내용 찾음 : 123 (4) 567,890 : 123 4, 56 7, 890
  • 조건에부합하는내용 찾음 : (1) 234, 567, 890 : 1, 23 4, 56 7, 890
  • 정리하면 입력된 내용에서 (1) 23 (4) 56 (7) 890 3개의 그룹을 발견했고, 해당 내용을 replace 매서드에 따라서 결과를 반환한 것이다.

03 이번주의 끄적임

EDWIN벨로그 - 라우터
EDWIN벨로그 - 프로미스(정리중)
EDWIN벨로그 - Redux에 대한 복습
EDWIN벨로그 - 옵셔널체이닝
EDWIN벨로그 - 정규표현식

04 정리하기

이번주는 정말 정신 없는 한 주를 보냈다. 분량이 과도했기 때문이다. 너무나 많은 분량에 무언가를 정리하고 기록할수조차 없었다. 그럼에도 위의 내용은 부지런히 정리해본 내용들이다. 정리하지 않으면 뇌에서 소멸되기 때문이다. 그래서 다음주는 보다 부지런히 정리하며, 내용을 복기해보고자 한다.

profile
신학전공자의 개발자 도전기!!

0개의 댓글