본문 바로가기
JAVASCRIPT/React

[생활코딩 React 강의] Immutable이란? (concat, shouldComponentUpdate, Array.from, Object.assign)

by sjs_2215 2019. 8. 20.

생활 코딩 리액트 강의 <https://www.youtube.com/playlist?list=PLuHgQVnccGMCRv6f8H9K5Xwsdyg4sFSdi


원본을 바꾸지 않는다 = immutable

  • concat 사용하기
  • Array.from 사용하기 [배열일때]
  • Object.assign 사용하기 [객체일때]



concat과 shouldComponentUpdate


1-1. concat이란


  • push와 concat 차이
var arr = {1,2};
arr.push(3);
arr //1,2,3 출력

var ar2 = {1,2};
var result=arr2.concat(3);
arr2 //1,2 출력
result //1,2,3 출력

push: 원본을 바꿈

concat: 원본 바꾸지 않음. 원본을 토대로 변경한 새로운 배열이 리턴됨.

=> state에다가 값을 추가할 때 push와 같은 원본 데이터를 변경하는 것 쓰지 말기

=>concat과 같은 세로운 데이터를 추가하는 것을 쓰자 (성능 개선할 때 편해짐)


push대신 concat 쓰게 변경한 코드

this.max_content_id=this.max_content_id+1;

var _contents = this.state.contents.concat(
          {id:this.max_content_id, title:_title, desc:_desc}
        )

//밑 부분 추가
this.setState({
    contents:_contents
});



1-2. 내가 정한 상황에서만 렌더링 해! shouldComponentUpdate


특징:

  • shouldComponentUpdate의 return값이 true이면 render()가 호출+ render이전에 shouldComponentUpdate가 호출된다.
class TOC extends Component {
  shouldComponentUpdate(){
    console.log('TOC render shouldComponentUpdate');
    return true;
  }

  • shouldComponentUpdate의 return값이 false이면 render()가 호출되지 않도록 약속되어 있다.
class TOC extends Component {
  shouldComponentUpdate(){
    console.log('TOC render shouldComponentUpdate');
    return false;
  }

  • shouldComponentUpdate를 이용해 새롭게 바뀐 값과, 그 전 값에 접근할 수 있다.
class TOC extends Component {
  shouldComponentUpdate(newProps, newState){
    console.log('TOC render shouldComponentUpdate'
    ,newProps.data
    ,this.props.data
  );
    return false;
  }

새로운 데이터를 추가한 상황)

newProps.data는 추가된 것까지 출력

this.props.data는 그 전의 상황을 출력

+return false로 해놔서 render() 가 돌아가지 않아 실제로 웹에는 데이터가 추가되지 않았음을 알 수 있음




1-3. TOC로 들어오는 데이터가 '바뀌었을 때만' render()를 호출하게 만들어보자


  • if문(전 데이터와 새로운 데이터가 같으면) return false로 render 안하겠다는 소리
  • 전 데이터와 새로운 데이터가 다르면 (=새로운 데이터가 들어왔다면) return true로 render() 돌릴거야@
shouldComponentUpdate(newProps, newState){
    console.log('TOC render shouldComponentUpdate'
    ,newProps.data
    ,this.props.data
  );
  if(this.props.data===newProps.data){
    return false;
  }
  return true;
}

=> 성능을 향상시킬 수 있는 방법!!!

이것이 가능한 이유는 바로 복제본을 사용하는 concat을 사용했기 때문.

만약, 원본을 바꾸는 push를 사용했다면, 이전값과 이후값이 같아지기 때문에 if문에 들어가지 않음.




2. Array.from

Array.from을 통해 배열을 복제 할 수 있다.


Array.from을 사용하면 push를 하던 concat을 하던 상관 X

this.max_content_id=this.max_content_id+1;

        var newContents = Array.from(this.state.contents);
        newContents.push({id:this.max_content_id, title:_title, desc:_desc});

        this.setState({
          contents:newContents
        });



3. Object.assign

Object.assign을 통해 객체를 복사할 수 있다.


var a = {name:'egoing'};
var b = Object.assign({},a);
console.log(a,b,a==b);


//출력 결과:
//{name: "egoing"}, {name: "egoing"}, false

a와 b는 같은 객체가 아니다. 내용은 같지만!




Immuatble -js 라이브러리 사용해보자!

https://github.com/immutable-js/immutable-js

명령어들의 일관성 없는 js의 단점

=> 이를 제어할 수 있는 명령어는 무조건 immutable 사용.


원본을 return하지 않고 무조건 원본을 복제한 것을 return해줌

ex. 코드)

<script src="immutable.min.js"></script>
<script>
  var map1 = Immutable.Map({ a: 1, b: 2, c: 3 });
  var map2 = map1.set('b', 50);
  map1.get('b'); // 2
  map2.get('b'); // 50
</script>

모든 명령어들이 원본에 대해 불변하기에 일관된 코드를 사용할 수 있다는 장점



Comments