React (5) shouldComponentUpdate
push와 concat
state에 배열이 있을 경우, 그 배열에 값을 추가할 때
push를 사용하면 그 원본 배열 자체가 변경되고
concat을 사용하면 새로운 배열이 만들어진다고 했다.
그래서, push를 사용하기보다는 concat을 사용하라고 했었다.
render의 문제
상위 component가 update될 경우, 하위 component의 render 함수가
자동으로 호출된다고 했는데, 이 메커니즘의 문제가 있다.
가끔 해당 하위 component와는 전혀 관련이 없는 데이터가 update 되는 경우에도
하위 component의 render가 호출되어 불필요한 렌더링이 발생하는 것이다.
shouldComponentUpdate
하위 component의 render함수가 아무때나 호출되지 않도록
조절할 수 있게 해주는 함수가 바로 shouldComponentUpdate이다.
-
shouldComponentUpdate함수는 render 함수보다 먼저 호출된다.
-
이 함수가 true를 return하면 render 함수가 호출되고
이 함수가 false를 return하면 render 함수는 호출되지 않는다. -
이 shouldComponentUpdate는 newProps와 newState를 인자로 받는다.
newProps로 바뀐 후의 새로운 props에 접근할 수도,
this.props로 바뀌기 전인 현재의 props에 접근할 수도 있다.
1, 2, 3을 모두 종합하면 다음과 같은 결과가 나온다.
→ newProps와 this.props를 비교해서, props의 값에 변화가 생겼다면
true를 return해서 render함수를 호출하고(화면을 새로 렌더링하고)
props값에 변화가 없다면 false를 return하서 render 함수가 호출되지 않도록 할 수 있다.
concat을 쓰는 이유
우리가 state에 있는 배열을 수정할 때 concat이 아니라 push를 이용해서 수정하면
push는 원본 자체를 바꿔버리기 때문에, this.props와 newProps의 값이 완전히 동일해진다.
→ shouldComponentUpdate 함수가 무용지물이 되어버린다.
immutable
원본을 바꾸지 않는다 = 불변성(immutable)
사실, push와 concat 중 무엇을 써야하는지를 매번 생각하기가 쉽지는 않다.
이럴 때는 그냥 Array.from()을 이용해서, 동일한 배열을 하나 새로 만들어
(그러면, 내용은 같지만 서로 다른 배열이 생성된다)
거기다가 push를 해주면 된다.
그러면 push를 사용하더라도 원본이 변할 일이 없다.
var newContents = Array.from(this.state.contents);
newContents.push({ id:this.max_content_id, title:_title, desc:_desc });
this.setState({ contents : _contents });
Array.from은 배열에만 사용할 수 있는 함수이다.
객체의 경우에는 동일한 역할을 할 수 있는 함수가 바로 Object.assign이라는 함수.
var a = {name: 'React'};
var b = Object.assign({}, a); // 새로운 빈 객체에다가 a를 복사해서 넣는다고 보면 됨.
b.name = "Redux";
console.log(a, b); // {name: 'React'} {name: 'Redux'}
참고로, Object.assign의 첫 번째 인자로 꼭 빈 객체를 넣어야되는 건 아님.
원래 Object.assign 함수는 첫 번째 인자의 객체에다가 두 번째 인자 객체를 넣어주는 함수.
var a = {name: 'React'};
var b = Object.assign({one: 1, two: 2});
console.log(a, b); // {name: 'React'} {one: 1, two: 2, name: 'React'}
Tip) debugger
코드 중간중간에 debugger;
라는 코드를 넣으면
코드를 실행시켰을 때, debugger 코드를 만나는 순간 코드 진행이 멈추게 된다.
해당 시점에서 변수같은 것들이 어떤 상황인지를 지켜볼 수가 있다.
디버깅에 유용한 코드.