Immutable(1) - MoonGyeongHyeon/React_Study GitHub Wiki

React - Immutable.js(1)

๋ถˆ๋ณ€ ๊ฐ์ฒด

๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ์žˆ์–ด์„œ ๋ถˆ๋ณ€ ๊ฐ์ฒด๋Š” ์ƒ์„ฑ ํ›„ ๊ทธ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋Š” ๊ฐ์ฒด๋ฅผ ๋งํ•œ๋‹ค. ๋ถˆ๋ณ€ ๊ฐ์ฒด์˜ ๋ฐ˜๋Œ“๋ง์€ ๊ฐ€๋ณ€ ๊ฐ์ฒด๋กœ Javascript์˜ ๋ฐฐ์—ด๊ณผ ๊ฐ™์ด ๊ฐ์ฒด ๋‚ด์—์„œ ๊ด€๋ฆฌํ•˜๋Š” ๊ฐ’์ด๋‚˜ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ค.

var greeting = new String('Hello World!!');

greeting.replace('World', 'Gil-dong');
greeting.valueOf(); // Hello World!!

์œ„์˜ ์˜ˆ์—์„œ greeting ๋ณ€์ˆ˜์— ๋ฌธ์ž์—ด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋Œ€์ž…ํ–ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ฌธ์ž์—ด ๊ฐ์ฒด์˜ replace ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด 'World'๋ฅผ 'Gil-dong'์œผ๋กœ ๋ณ€๊ฒฝํ–ˆ๋‹ค. ํ•˜์ง€๋งŒ ์—ฌ์ „ํžˆ greeting ๋ณ€์ˆ˜๋Š” 'Hello World!!'์ด๋‹ค.

greeting ๋ณ€์ˆ˜์— ์ƒ์„ฑํ•œ ๋ฌธ์ž์—ด ๊ฐ์ฒด๋Š” ๋ถˆ๋ณ€ ๊ฐ์ฒด์ด๋ฏ€๋กœ ๊ฐ’์„ ๋ฐ”๊ฟ€์ˆ˜ ์—†๋‹ค. ๋”ฐ๋ผ์„œ replace ๋ฉ”์†Œ๋“œ๋Š” ์ƒˆ๋กœ์šด ์ƒํƒœ๋ฅผ ๊ฐ€์ง€๋Š” ๋˜ ๋‹ค๋ฅธ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ ๋’ค ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๋ณ€์ˆ˜์— ๊ฐ’์„ ๋ฐ”๊พธ๊ธฐ ์œ„ํ•ด์„  ์•„๋ž˜์ฒ˜๋Ÿผ ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ๋ณ€์ˆ˜์— ๋Œ€์ž…ํ•ด์•ผ ํ•œ๋‹ค.

var greeting = new String('Hello World!!');

greeting = greeting.replace('World', 'Gil-dong');
greeting.valueOf(); // Hello Gil-dong!!

๊ฐ’ ๊ฐ์ฒด

์ด๋Ÿฌํ•œ ๋ถˆ๋ณ€ ๊ฐ์ฒด์˜ ํŠน์„ฑ์€ number, string, boolean ์—์„œ ์ฐพ์•„๋ณผ ์ˆ˜ ์žˆ๋‹ค. ๊ฐ’ ๊ฐ์ฒด๋ž€ ๋น„๊ต ์—ฐ์‚ฐ ์‹œ ์ž์‹ ์˜ ์ƒํƒœ๋ณด๋‹ค ๊ฐ’์„ ์šฐ์„ ์‹œํ•˜๋Š” ๋‹จ์ˆœํ•œ ๊ฐ์ฒด๋ฅผ ๋งํ•œ๋‹ค.

React์—์„œ ๋ถˆ๋ณ€์„ฑ?

React ์ปดํฌ๋„ŒํŠธ์—์„œ๋Š” state ๋‚˜ ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ „๋‹ฌ๋ฐ›์€ props ๊ฐ’์ด ๋ณ€ํ•  ๋•Œ ๋ฆฌ๋ Œ๋”๋ง์„ ํ•ด์•ผํ•˜๋Š”๋ฐ ๋งŒ์•ฝ ๋ฐฐ์—ด์ด๋‚˜ ๊ฐ์ฒด๋ฅผ ์ง์ ‘์ ์œผ๋กœ ์ˆ˜์ •ํ•œ๋‹ค๋ฉด, ๋‚ด๋ถ€์˜ ๊ฐ’์ด ์ˆ˜์ •๋์„์ง€๋ผ๋„ ๋ ˆํผ๋Ÿฐ์Šค๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ณณ์€ ๋˜‘๊ฐ™๊ธฐ ๋•Œ๋ฌธ์— ๋˜‘๊ฐ™์€ ๊ฐ’์œผ๋กœ ์ธ์‹ํ•˜์—ฌ ๋ฆฌ๋ Œ๋”๋ง์„ ํ•˜์ง€ ์•Š๋Š”๋‹ค.

์ด๋Ÿฌํ•œ ํŠน์ง•๋•Œ๋ฌธ์— ๊ฐ„๋‹จํ•œ ์ž‘์—…์„ ํ•˜๋”๋ผ๋„ ์ฝ”๋“œ๊ฐ€ ๋ณต์žกํ•ด์งˆ ์ˆ˜ ์žˆ๋‹ค. ์•„๋ž˜์˜ ์ฝ”๋“œ๋ฅผ ๋ณด์ž.

let object1 = {
    a: 1,
    b: 2,
    c: 3,
    d: {
        e: 4,
        f: { 
            g: 5,
            h: 6
        }
    }
};

// h๊ฐ’์„ 10์œผ๋กœ ์—…๋ฐ์ดํŠธํ•จ
let object2 = {
    ...object1,
    d: {
        ...object1.d,
        f: {
            ...object1.d.f,
            h: 10
        }
    }
}

๋งŒ์•ฝ ๊ฐ์ฒด์˜ ๋ถˆ๋ณ€์„ฑ์„ ์œ ์ง€ํ•  ํ•„์š”๊ฐ€ ์—†์—ˆ๋‹ค๋ฉด object1.d.f.h = 10; ์œผ๋กœ ๊ฐ„๋‹จํ•˜๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์—ˆ์„ ๊ฒƒ์ด๋‹ค.

๋ฐฐ์—ด์˜ ๊ฒฝ์šฐ๋„, ๋ฐฐ์—ด ์•ˆ์— ์žˆ๋Š” ๊ฐ’์„ ์ˆ˜์ •ํ•˜๋ ค๋ฉด ์ˆ˜์ •ํ•˜๋ ค๋Š” ์›์†Œ ์œ„์น˜์˜ ์•ž/๋’ค๋กœ slice ํ•ด์„œ ๊ฐ€์ ธ์™€์•ผ ํ•˜๋Š”๋ฐ, ์—ฌ๊ฐ„ ๊ท€์ฐฎ์€ ์ผ์ด ์•„๋‹ˆ๋‹ค.

์ด๋ฅผ ์œ„ํ•ด...

Immutable.js๋Š” ์œ„์™€ ๊ฐ™์€ ๋ถˆ๋ณ€ ๋ฐ์ดํ„ฐ๋ฅผ ์œ„ํ•ด ๋“ฑ์žฅํ–ˆ๋‹ค. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด,

let object1 = Map({
    a: 1,
    b: 2,
    c: 3,
    d: Map({
        e: 4,
        f: Map({ 
            g: 5,
            h: 6
        })
    })
});

let object2 = object1.setIn(['d', 'f', 'h'], 10);

object1 === object2;
// false

์œ„์™€ ๊ฐ™์ด ๊ฐ„๊ฒฐํ•ด์ง„ ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

์‚ฌ์šฉ๋ฐฉ๋ฒ•

Immutable์˜ Map ์€ ๊ฐ์ฒด ๋Œ€์‹  ์‚ฌ์šฉ๋˜๋Š” ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋‹ค. ์ด๋Š”, Javascript์— ๋‚ด์žฅ๋˜์–ด์žˆ๋Š” Map ๊ณผ๋Š” ๋‹ค๋ฅด๋‹ค.

var Map = Immutable.Map;

var data = Map({
  a: 1,
  b: 2,
  c: Map({
    d: 3,
    e: 4,
    f: 5
  })
})

์œ„์™€ ๊ฐ™์ด Map ํ•จ์ˆ˜ ์•ˆ์— ๊ฐ์ฒด๋ฅผ ๋„ฃ์–ด ํ˜ธ์ถœํ•˜๋ฉด ๋œ๋‹ค. ๋งŒ์•ฝ, ๊ฐ์ฒด ๋‚ด๋ถ€์— ๋˜๋‹ค๋ฅธ ๊ฐ์ฒด๊ฐ€ ์žˆ๋‹ค๋ฉด ๊ทธ ๊ฐ์ฒด๋„ ๊ฐ์‹ธ์•ผํ•œ๋‹ค.

Map ํ•จ์ˆ˜๊ฐ€ ์•„๋‹Œ fromJS ๋ฅผ ์‚ฌ์šฉํ•ด๋„ ๋œ๋‹ค.

var fromJS = Immutable.fromJS;

var data = fromJS({
  a: 1,
  b: 2,
  c: { 
    d: 3,
    e: 4,
    f: 5
  }
});

fromJS ๋Š” ๋‚ด๋ถ€ ๊ฐ์ฒด๋“ค๋„ ํ•œ๋ฒˆ์— Map์œผ๋กœ ๋ณ€ํ™˜ํ•ด์ค€๋‹ค.

Map ํ•จ์ˆ˜๋‚˜ fromJS ํ•จ์ˆ˜๋กœ ๋งŒ๋“  Map์„ ๋กœ๊ทธ๋กœ ์ฐ์–ด๋ณด๋„๋ก ํ•˜์ž.

[object Object] {
  @@__IMMUTABLE_ITERABLE__@@: true,
  @@__IMMUTABLE_KEYED__@@: true,
  @@__IMMUTABLE_MAP__@@: true,
  __altered: false,
  __ensureOwner: function (t){return t===this.__ownerID?this:t?Yt(this.size,this._root,t,this.__hash):(this.__ownerID=t,this.__altered=!1,this)},
  __hash: undefined,
  __iterate: function (t,e){var r=this,n=0;return this._root&&this._root.iterate(function(e){return n++,t(e[1],e[0],r)},e),n},
  __iterator: function (t,e){return new Ht(this,t,e)},
  __ownerID: undefined,
  __toJS: function (){st(this.size);var t={};return this.__iterate(function(e,r){t[r]=e}),t},
  __toString: function (t,e){return 0===this.size?t+e:t+
...

์œ„์™€ ๊ฐ™์ด ๋‚˜์˜จ๋‹ค. Map์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•  ์ˆœ ์—†๋‹ค. console.log(data.a) // undefined ์™€ ๊ฐ™์€ ํ‘œํ˜„๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.

Mapd์€ ์ผ๋ฐ˜ ๊ฐ์ฒด๊ฐ€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ณ„๋„์˜ ๋ฐฉ๋ฒ•์œผ๋กœ ๋‹ค๋ค„์ค˜์•ผ ํ•œ๋‹ค.

  • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ

    Map์„ ์ผ๋ฐ˜ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

    data.toJS();  // { a:1, b:2, c: { d: 3, e: 4 } }
    

    toJS() ํ•จ์ˆ˜๋Š” Map์„ ์ผ๋ฐ˜ Javascript ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•ด์ค€๋‹ค.

  • ํŠน์ • ํ‚ค๊ฐ’ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ๋ฐ ์„ค์ •ํ•˜๊ธฐ

    Map์˜ ํŠน์ • ํ‚ค๊ฐ’๋งŒ์„ ๋ถˆ๋Ÿฌ์˜ค๊ณ  ์‹ถ๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•  ์ˆ˜ ์žˆ๋‹ค.

    data.get('a');  // 1
    var newData = data.set('a', 4);
    

    get() ํ•จ์ˆ˜๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ „๋‹ฌ๋œ key์˜ ๊ฐ’์„ ๋ถˆ๋Ÿฌ์˜จ๋‹ค. set() ํ•จ์ˆ˜๋Š” ๊ฐ’์„ ์„ค์ •ํ•œ๋‹ค.

    set ํ•จ์ˆ˜๋ฅผ ํฌํ•จํ•ด์„œ ์–ด๋– ํ•œ ๊ฐ’์„ ์„ค์ •ํ•˜๋Š” ํ•จ์ˆ˜๋Š” ๊ธฐ์กด์˜ ๊ฐ’์„ ๋ฐ”๊พธ๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ, ์ฃผ์–ด์ง„ ๋ณ€ํ™”๋ฅผ ์ ์šฉ์‹œํ‚จ ์ƒˆ๋กœ์šด Map์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

  • ๊นŠ์ˆ™ํ•œ ๊ฐ’ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ๋ฐ ์„ค์ •ํ•˜๊ธฐ

    ๊นŠ์ˆ™ํžˆ ๋“ค์–ด์žˆ๋Š” ๊ฐ’์„ ๋ถˆ๋Ÿฌ์˜ค๊ณ  ์„ค์ •ํ•ด์•ผ ํ•  ๋• getIn ๊ณผ setIn ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

    data.getIn(['c', 'd']) // 3
    var newData = data.setIn(['c', 'd'], 10);
    
  • ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๊ฐ’ ์„ค์ •ํ•˜๊ธฐ

    ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๊ฐ’์„ ๋™์‹œ์— ์„ค์ •ํ•  ๋•Œ๋Š” mergeIn ์„ ์‚ฌ์šฉํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, c.d์™€ c.e์˜ ๊ฐ’์„ ๋™์‹œ์— ๋ฐ”๊ฟ”์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ, setIn์„ 2๋ฒˆ ํ˜ธ์ถœํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ ์•„๋ž˜์™€ ๊ฐ™์ด ํ•œ๋ฒˆ์— ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

    var newData = data.mergeIn(['c'], { d: 10, e: 10 });
    

    ์ด๋ ‡๊ฒŒ ํ–ˆ์„ ๋•Œ, c.f์˜ ๊ฐ’์€ ๊ทธ๋Œ€๋กœ ์œ ์ง€๋œ๋‹ค.

    ์ตœ์ƒ์œ„์—์„œ merge๋ฅผ ํ•ด์•ผํ•œ๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ํ•œ๋‹ค.

    var newData = data.merge({ a: 10, b: 10 })
    
  • ์ „์ฒด ๊ฐ์ฒด ์—…๋ฐ์ดํŠธํ•˜๊ธฐ

    ์ „์ฒด ๊ฐ์ฒด๋ฅผ ์—…๋ฐ์ดํŠธ ํ•  ๋•Œ๋Š” merge๋ณด๋‹ค ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒŒ ์ข‹๋‹ค.

    var newData = data.set('c', Map({ d: 10, e: 10, f: 10 }))
    

    โ€‹