본문 바로가기

Hanghae99

221130 TIL 팀별 과제 정리

Q1.  리액트에서  불변성을 지켜야하나요?

  •  리액트에서는 상태값을 업데이트할 때 얕은 비교를 수행합니다.
얕은 비교(Shallow Compare)란? 
얕은 비교는 자료형에 따라 데이터 비교 방법이 다르다. 숫자, boolean과 같은 원시 자료형에 경우에는 그 값을 비교하고, 배열, 객체 등과 같은 참조 자료형에 경우에는 그 속성 (attributes)을 비교하는 것이 아니라 참조주소값(reference)을 비교하는데, 이것을 얕은 비교하고 합니다.
  •  그렇기 때문에 리액트에서는 객체와 같은 데이터에 변경이 있을 경우에는 속성에 변경이 있더라도 참조주소값에 변경이 없으면 그 변경을 인지하지 못합니다.
  •  따라서, 리액트에서 객체에 변화가 있다면 그 참조 주소값을 변경해주어야 하는 것 입니다.

 

이것이 불변성이랑 무슨 관계일까요?

  •  먼저 불변성이 무엇인지를 알아야 합니다.
불변성이란?
 - 일차원적으로는 값이나 상태를 변경할 수 없는 것을 의미합니다.
 - 불변성은 원시자료형과 참조자료형의 메모리 할당방식에 따라 다르게 나타납니다.
 - 원시 자료형에 경우에는 어떤 변수의 데이터가 선언되었을때 고정된 메모리에 할당된 원시자료형에 변수가 할당됩니다.
 - 따라서 같은 변수의 데이터가 변경이 되었을때 고정되어 있는 다른 메모리로 할당되어 참조주소값이 변경됩니다.
 - 이때 할당된 메모리에 있는 데이터값이 변경되지 않고 유지되기 때문에 원시자료형은 "불변성을 가지고 있다." 라고 표현하게 됩니다.
 - 그러나, 참조 자료형에 경우에는 다릅니다.
 - 참조 자료형에 경우에는 변수가 선언되었을때 일정한 메모리에 데이터를 저장합니다.
 - 그리고 데이터에 변경이 있는 경우에는 같은 메모리에 있는 데이터 자체를 변경하게 됩니다.
 - 이때 같은 메모리에 데이터가 변경되기 때문에 참조자료형에는 "불변성이 없다." 라고 표현할 수 있습니다.
 - 따라서 불변성이란 "메모리 영역에서 데이터값이 변하지 않는 것" 이라고 정의할 수 있습니다.

리액트에서 불변성을 지켜준다는 것은 무슨 의미일까요?

  • 앞에서 말했듯이 리액트에서는 데이터를 비교할때 얕은 비교를 합니다.
  • 그러나 객체와 같은 참조 자료형은 데이터에 변경이 있을 경우 메모리 주소값은 변하지 않고 데이터 자체가 변경되기 때문에 참조 주소값을 비교하는 리액트에서는 그 변화를 인지하지 못하는 것입니다.
  • 그렇기 때문에 리액트에서 객체의 속성을 변경할 경우에는 새로운 객체를 복사하여 그 값을 변경해 줍니다.
  • 이 때 원본 객체는 할당되었던 메모리 영역에서 데이터 값이 변경되지 않고 유지되기 때문에 그대로 불변성을 지키고 있습니다.
  • 이것을 리액트에서는 "불변성을 지켜준다." 라고 표현을 하는 것입니다.

리액트에서는 왜 얕은 비교를 수행하는 걸까요?

Shallow compare is an efficient way to detect changes.
  • 그 이유는 얕은 비교는 계산 리소스를 줄여주므로 효율적이기 때문이다.
  • 속성의 값을 하나 하나 비교하는 깊은 비교보다는 주소값만을 비교해주면 되기때문에 변화를 감지하는것이 용이하다.

객체 변경없이 새로운 객체를 생성하여 데이터를 수정하는 것의 이점

  1. 특정 행동을 취소하고 다시 실행하는 기능과 같은 복잡한 기능을 비교적 단순하게 구현가능하게 합니다. 왜냐하면 이전 할당되었던 메모리의 값이 불변성을 유지하고 그대로 있기 때문이죠.
  2. 참조하고 있는 객체의 주소가 변경된 것을 감지하는 것이 변화를 감지하는데 가장 확실한 방법입니다.
  3. 리액트에서 리렌더링하는 시기를 결정할수 있습니다.
    순수 컴포넌트는 입력된 값을 받아 그대로 출력합니다. 이러한 경우 데이터값은 변경되지 않았지만 새로운 객체가 생성되기 때문에 리렌더링을 할 수 있습니다.
  4. 사이드 이펙트를 방지 및 프로그래밍 구조의 단순성
     원본 데이터가 변경될 경우, 이 원본데이터를 참조하고 있는 다른 객체에서 예상치 못한 오류가 발생할 수 있습니다. 또한 프로그래밍의 복잡도도 올라갑니다.
    즉, 외부에 존재하는 원본데이터를 직접 수정하지 않고, 원본데이터의 복사본을 만들어서 값을 사용하기에 예상치 못한 오류를 사전에 방지할 수 있습니다.

  5. 효율적인 상태 업데이트 (얕은 비교 수행)
     객체의 참조 주소값만 변경되었는지 확인합니다. 얕은 비교는 계산 리소스를 줄여주기 때문에 리액트는 효율적으로 상태를 업데이트 할 수 있습니다.

어떻게 불변성을 지키나요?

  • 불변성을 지키기 위해서 리액트에서는 새로운 배열 혹은 객체를 반환하는 메소드들을 활용합니다.
  • spread operator, map, filter, slice, reduce 등등을 주로 사용합니다.
  • splice는 기존 배열에 변화를 주기 때문에 주의해야 합니다.
  • setState를 사용하는 경우에는 원시 자료형에 경우에는 값을 바로 넣어주어도 값이 저장되어있는 참조 주소가 변경되기 때문에 바로 넣어주어도 되지만
  • 참조 자료형에 경우에는 새로운 객체나 배열을 생성한 후에 값을 넣어주어야 합니다.

 

1. 자바스크립트에서 유사배열과 배열의 차이는 무엇일까요? 유사배열의 각 요소를 수정하고 싶다면 어떤 과정을 거쳐야할까요?

 

2. 부모 컴포넌트 A와 자식 컴포넌트 B가 있습니다. 컴포넌트 A는 state로 {name: "르탄이"}를 가지고 있고, 자식인 컴포넌트 B에게 name 값을 넘겨주었습니다. 컴포넌트 B는 받아온 name을 화면에 뿌려주고 있습니다. 컴포넌트 A의 state가 {name: "진도사우르스"}로 바뀌었을 때, 어떤 과정을 거쳐 바뀐 값을 화면에 보여주는 지 라이프 사이클 흐름을 그려볼까요?

 

3. 양방향 바인딩은 무엇일까요? 양방향 바인딩을 사용하는 경우 리렌더링이 어떻게 이루어질 지 그려보세요. (부모 컴포넌트 A와 자식 컴포넌트 B가 있음을 가정하고 그려봅시다.)

 

4. event listener는 등록되면 반드시 해제되어야 합니다. 클래스형 컴포넌트에서는 컴포넌트가 화면에서 사라질 때(unmount 될 때) event listener를 해제합니다. (componentWillUnmount에서요!) 그럼 라이프사이클 메소드를 사용할 수 없는 함수형 컴포넌트에서는 event listener를 해제할 때 어떻게 해야할까요?

 

5. 리액트에서는 DOM 요소에 접근하기 위해 주로 ref를 씁니다. domcument.getElementsByClassName 등을 쓰는 게 아니라 ref를 쓰는 이유는 무엇일까요?

 

6. SPA 방식과 MPA 방식은 무엇인가요?