shouldComponentUpdate 란?
-
얘는 state가 변경되거나 부모 컴포넌트로부터 새로운props를 전달받을 때 실행되는 메소드다.
-
React는 이 메소드(shouldComponentUpdate)의 반환 값에 따라 re-render를 할지에 대한 여부를 결정
-
shouldComponentUpdate 메소드는 true를 반환 (But React 개발자는 re-render를 원치않으면, return false로 놓고 할 수 있다.)
요새 고민은...
<App> 부모가 호출되면 → 하위 자식들 <Subject><Main><Control><ReadContent>등.. 렌더함수가 줄줄이 호출된다.
그리고 그 자식 중 하나인 <Main> 은 create에 입력하면 그 글을 글 목록에 추가시켜주는 역할을 한다.
BUT 불합리하다. create기능 안써도 <Main>같이 딱히 필요없는 자식도 매번 불필요하게 호출되어야 하다니...
**코드보기(복사용 첨부 / 더보기클릭)
import React, { Component } from 'react';
import Subject from "./components/Subject.js";
import Main from "./components/Main.js";
import Control from "./components/Control.js";
import CreateContent from "./components/CreateContent.js";
import ReadContent from "./components/ReadContent.js";
import './App.css';
class App extends Component {
constructor(props){
super(props);
this.max_content_id = 3;
this.state = {
mode:'read',
selected_content_id:1,
head:{title:'WEB', sub:'world wide web!'},
welcome:{title:'Welcome', desc:'Hello, React!!'},
contents:[
{id:1, title:'HTML', desc:'HTML is for information'},
{id:2, title:'CSS', desc:'CSS is for design'},
{id:3, title:'JavaScript', desc:'JavaScript is for interactive'}
]
}
}
render() {
console.log('App render');
var _title, _desc, _article = null;
if(this.state.mode === 'welcome'){
_title = this.state.welcome.title;
_desc = this.state.welcome.desc;
_article = <ReadContent title={_title} desc={_desc}></ReadContent>
} else if(this.state.mode === 'read'){
var i = 0;
while(i < this.state.contents.length){
var data = this.state.contents[i];
if(data.id === this.state.selected_content_id) {
_title = data.title;
_desc = data.desc;
break;
}
i = i + 1;
}
_article = <ReadContent title={_title} desc={_desc}></ReadContent>
} else if(this.state.mode === 'create'){
_article = <CreateContent onSubmit={function(_title, _desc){
// add content to this.state.contents
this.max_content_id += 1;
var _contents = this.state.contents.concat(
{id:this.max_content_id, title:_title, desc:_desc}
);
this.setState({
contents:_contents
});
console.log(_title, _desc);
}.bind(this)}></CreateContent>
}
return(
<div className="App">
<Subject
title={this.state.head.title}
sub={this.state.head.sub}
onChangePage={function(){
this.setState({mode:'welcome'});
}.bind(this)}>
</Subject>
<Main
onChangePage={function(id){
this.setState({
mode:'read',
selected_content_id:Number(id)
});
}.bind(this)}
data={this.state.contents}>
</Main>
<Control onChangeMode={function(_mode){
this.setState({
mode:_mode
})
}.bind(this)}></Control>
{_article}
</div>
);
}
}
export default App;
그래서 shouldComponentUpdate로 고민해결!
얘를 써서 렌더직전에 막아서 사용하지 않을 때 렌더함수가 호출이 되지 않게 만들 수 있다.
이 함수는 두개의 매개변수를 가지도록 되어있다.
newProps.data(업데이트된 값) = this.props.data(현재 값) 이면
→ 값의 변경이 없다는 의미, 렌더함수 실행 x (글목록 클릭만 한다면 Main의 렌더가 실행x)
newProps.data(업데이트된 값) != this.props.data(현재 값) 이면
→ 값의 변경이 있다는 의미, 렌더함수 실행 o (create로 글을 입력하면 Main의 렌더가 실행o)
**코드보기(복사용 첨부 / 더보기클릭)
import React, { Component } from 'react';
class Main extends Component {
shouldComponentUpdate(newProps, newState){
console.log(
'====>Main render shouldComponentUpdate',
newProps.data,
this.props.data
);
if(this.props.data === newProps.data){
return false;
}
return true;
}
render() {
console.log('Main render');
var lists = [];
var data = this.props.data;
var i = 0;
while(i<data.length){
lists.push(
<li key={data[i].id}>
<a
href={"/content/"+data[i].id}
data-id={data[i].id}
onClick={function(e){
e.preventDefault();
this.props.onChangePage(e.target.dataset.id);
}.bind(this)}>
{data[i].title}
</a>
</li>
);
i = i+1;
}
return(
<nav>
<ul>
{lists}
</ul>
</nav>
);
}
}
export default Main;
concat()을 함께 써야하는 이유
shouldComponentUpdate의 값을 비교할 때 push()를 사용하면 원본배열을 건드리기때문에 비교자체가 불가하다 (문제가 생긴다.)
concat을 사용한다면 원본배열은 그대로 유지하면서 업데이트된 값이랑 같은지 비교 가능하기 때문에 문제없이 진행된다.
실행화면
shouldComponentUpdate가 false일 때,
shouldComponentUpdate가 true일 때,
**push와 concat의 차이점(더보기클릭)
push와 concat의 공통점은 데이터를 배열 안에 추가할 때 사용한다는 점이다.
push는 데이터 추가된 사항이 배열의 원본에 적용되며 (마치 파일에 그대로 저장st)
concat은 원본은 그대로 남기고 copy된 배열로 데이터가 추가된 배열이 생성된다. (마치 다른이름으로 저장st)
'React' 카테고리의 다른 글
React(18) Update 구현 (0) | 2021.01.12 |
---|---|
React(17) Immutable 개념 (0) | 2021.01.08 |
React(15) Create 구현 : onSubmit이벤트 & contents변경 (0) | 2021.01.07 |
React(14) Create 구현 : 모드 전환 & form 생성 (0) | 2021.01.06 |
React(13) Create구현 : 모드 변경 (0) | 2021.01.06 |
댓글