ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [React] μ™œ μƒνƒœκ°’μ΄ λ°”λ€Œλ©΄ λ¦¬λ Œλ”λ§λ κΉŒ? (feat. Closure)
    🧚 λ§ˆλ²•μ„ κ³Όν•™μœΌλ‘œ 2023. 2. 20. 15:49

     

     

    πŸ‹ μ„œλ‘ 


    λ¦¬μ•‘νŠΈλ₯Ό 잘 μ‚¬μš©ν•˜λŠ” λ‹¨κ³„λŠ” κ±°μ³€κ³ , λ‹Ήμ—°ν•œ 것듀에 μ™œ?λΌλŠ” μ§ˆλ¬Έλ“€ 마ꡬ λ˜μ§€λŠ” μš”μ¦ˆμŒ,

    λ¦¬μ•‘νŠΈκ°€ λ¦¬λ Œλ”λ§ λ˜λŠ” μ‹œμ , 즉 μƒνƒœκ°’κ³Ό 프둭이 μ—…λ°μ΄νŠΈλ˜λŠ” μ‹œμ μ— μ–΄λ– ν•œ 일듀이 μΌμ–΄λ‚˜λŠ”μ§€ κΆκΈˆν•΄μ‘Œλ‹€.

    ν©μ–΄μ Έμžˆλ˜ μ»¨ν…μŠ€νŠΈ-클둜져-λ¦¬μ•‘νŠΈ 퍼즐을 맞좜 수 μžˆλŠ” μ‹œκ°„μ΄μ—ˆλ‹€.

     

     

    πŸ‹ μ‚¬μ „ 지식


    ν΄λ‘œμ Έλž€ 무엇인가? λ‚΄κ°€ μƒκ°ν•˜κΈ°μ—λŠ” μ–΄λ– ν•œ λͺ¨λ¨ΌνŠΈμ΄λ‹€. λ ‰μ‹œμ»¬ μŠ€μ½”ν”„ λ°–μ—μ„œ λ ‰μ‹œμ»¬ μŠ€μ½”ν”„ λ‚΄λΆ€λ₯Ό κΈ°μ–΅ν•˜κ³  μ ‘κ·Όν•  수 μžˆλŠ”. 이 말에 λŒ€ν•œ μ„€λͺ…이 와닿지 μ•Šλ‹€λ©΄ μ•„λž˜ πŸ‹ μ „μ—­ μ»¨ν…μŠ€νŠΈ & ν•¨μˆ˜ μ»¨ν…μŠ€νŠΈ λΆ€λΆ„λΆ€ν„° 읽어보길 μΆ”μ²œν•œλ‹€. 

     

     

    πŸ‹ useState 훅이 μ–΄λ–»κ²Œ μƒκ²ΌλŠ”κ°€


    μ•„λž˜λŠ” λ°”λ‘œ μ‚¬μš©μ€ μ΅μˆ™ν•˜μ§€λ§Œ, μ–΄λ–»κ²Œ μƒκ²ΌλŠ”μ§€λŠ” μƒμ†Œν•œ useState ν›…μ˜ μƒκΉ€μƒˆμ΄λ‹€. (μ½”λ“œμ°Έκ³ λ§ν¬)

    const React = (() => { 
      let val; // -- 1
      const useState = (initialValue) => {
        val = val || initialValue;
        const setState = (newVal) => {
          val = newVal;
        };
        return [val, setState];
      };
      return { useState }; 
    })();
    
    const App = () => {
      const [state, setState] = React.useState(0); // -- 2
    	setState(1) 
      return <></>
    };
    
    

    React ν•¨μˆ˜λŠ” React 라이브러리λ₯Ό, κ·Έ λ‚΄λΆ€ useState ν•¨μˆ˜λŠ” useState 훅을 μ§€μΉ­ν•œλ‹€.

    μ΄λ•Œ 쓰인 useState ν•¨μˆ˜λŠ” 클둜져 ν•¨μˆ˜λ‘œ, κ·Έ μƒμœ„ μŠ€μ½”ν”„μ— μžˆλŠ” let val; λ³€μˆ˜λ₯Ό μ°Έμ‘°ν•œλ‹€.

    App ν•¨μˆ˜λŠ” App μ»΄ν¬λ„ŒνŠΈλ₯Ό μ˜λ―Έν•œλ‹€.

    λ‚΄λΆ€μ—μ„œ μ‚¬μš©λœ state와 setStateλŠ” React ν•¨μˆ˜ λ‚΄ useState ν•¨μˆ˜μ—μ„œ λ°˜ν™˜ν•œ μƒνƒœκ°’κ³Ό μ„Έν„° ν•¨μˆ˜λ₯Ό μ§€μΉ­ν•˜κ³ , 이 λ‘˜μ€ 같은 μŠ€μ½”ν”„λ₯Ό κ³΅μœ ν•œλ‹€.

    setStateλŠ” κ³„μ†ν•΄μ„œ λ™μΌν•œ μƒμœ„ val 값을 μ—…λ°μ΄νŠΈμ‹œν‚€κ²Œ 되고, κ·Έ 값은 setState ν•¨μˆ˜κ°€ μ‚¬μš©λœ μŠ€μ½”ν”„μ—μ„œ κ³΅μœ λœλ‹€.

    ν•˜μ§€λ§Œ state λ³€μˆ˜λŠ” μ—…λ°μ΄νŠΈ 이전에 값이 μ €μž₯된 μƒνƒœλ‘œ, stateμ—μ„œ κ³„μ†ν•΄μ„œ μ—…λ°μ΄νŠΈλœ 값을 보여주기 μœ„ν•œ 방법이 ν•„μš”ν•˜μ‘Œλ‹€.

    μ΄λ•Œ setState ν•¨μˆ˜μ—μ„œ μƒνƒœκ°’ 즉, λ‚΄λΆ€ val λ³€μˆ˜μ— λ³€ν™”κ°€ μžˆμ„ λ•Œλ§ˆλ‹€ μ»΄ν¬λ„ŒνŠΈλ₯Ό λ¦¬λ Œλ”λ§ μ‹œμΌœμ£Όκ²Œ 되면, useState 훅이 μ‚¬μš©λœ μ‹œμ μ˜ μ½”λ“œ (2)κ°€ 또 ν•œλ²ˆ μ‹€ν–‰λ˜κΈ° λ•Œλ¬Έμ— stateλ₯Ό λ™κΈ°μ μœΌλ‘œ μ—…λ°μ΄νŠΈ μ‹œμΌœμ€„ 수 μžˆκ²Œλœλ‹€.

     

    πŸ‹ ν•œμ€„ μš”μ•½!


    λ¦¬λ Œλ”λ§μ€ μƒνƒœκ°’μ˜ 동기적인 μ‹œκ°μ  μ—…λ°μ΄νŠΈλ₯Ό μœ„ν•œ λΆˆκ°€ν”Όν•œ 선택인 것 κ°™λ‹€! λ•…λ•…λ•…

    참고자료:

    useState λ™μž‘ 원리

     

     

    πŸ‹ μ „μ—­ μ»¨ν…μŠ€νŠΈ & ν•¨μˆ˜ μ»¨ν…μŠ€νŠΈ?


    μ½”λ“œλ₯Ό 처음 μ‹€ν–‰ν•˜λŠ” μˆœκ°„ λͺ¨λ“  것(μ „μ—­ μŠ€μ½”ν”„, κ·Έκ³³μ—μ„œ μœ νš¨ν•œ λ³€μˆ˜ λ“± μ „μ—­μ μœΌλ‘œ κ΄€λ¦¬λ˜λŠ” 정보)을 κ΄€λ¦¬ν•˜λŠ” ν™˜κ²½μΈ μ „μ—­ μ»¨ν…μŠ€νŠΈκ°€ μƒμ„±λ˜κ³  μ΄λŠ” νŽ˜μ΄μ§€κ°€ μ’…λ£Œλ  λ•ŒκΉŒμ§€ μœ μ§€λ©λ‹ˆλ‹€.

    그리고 μ½”λ“œμ—μ„œ 각 ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•  λ•Œλ§ˆλ‹€ ν•¨μˆ˜ μ»¨ν…μŠ€νŠΈκ°€ ν•˜λ‚˜μ”© μƒκΈ°κ²Œ λ˜λŠ”λ° κ·Έ μ•ˆμ— ν•¨μˆ˜μ— λŒ€ν•œ 정보 즉, λ³€μˆ˜, μŠ€μ½”ν”„ 체인, thisκ°€ μƒμ„±λœλ‹€.

    νŠΉμ • ν•¨μˆ˜ μ»¨ν…μŠ€νŠΈμ—μ„œ λ³€μˆ˜λ₯Ό 찾을 λ•Œ 전달받은 객체에 μ—†λ‹€λ©΄ μŠ€μ½”ν”„ 체인을 따라 μ˜¬λΌκ°€λ©° 찾게 됨.

    ν΄λ‘œμ € ν•¨μˆ˜λ₯Ό μ œμ™Έν•˜κ³  ν•¨μˆ˜ 싀행이 μ™„λ£Œλ˜λ©΄ ν•΄λ‹Ή ν•¨μˆ˜ μ»¨ν…μŠ€νŠΈλŠ” μ‚¬λΌμ§‘λ‹ˆλ‹€.

     

    πŸ‹ μŠ€μ½”ν”„?


    참쑰될 수 μžˆλŠ” μœ νš¨ν•œ λ²”μœ„λ₯Ό λœ»ν•©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ λ³€μˆ˜ A의 μŠ€μ½”ν”„ == λ³€μˆ˜ Aκ°€ 참쑰될 수 μžˆλŠ” μœ νš¨ν•œ λ²”μœ„μž…λ‹ˆλ‹€.

    μŠ€μ½”ν”„μ™€ κ΄€λ ¨ν•΄μ„œ κΈ°μ–΅ν•΄μ•Όν•  ν‚€μ›Œλ“œκ°€ μžˆμŠ΅λ‹ˆλ‹€.

    1. 암묡적 μ „μ—­(implied globals):

    λ³€μˆ˜ μ•žμ— νƒ€μž…μ„ μ§€μ •ν•΄μ£Όμ§€ μ•ŠμœΌλ©΄ 암묡적 μ „μ—­λ³€μˆ˜κ°€ 됨.

    function foo() {
      x = 1;   // Throws a ReferenceError in "use strict" mode
      var y = 2;
    }
    
    foo();
    
    console.log(x); // 1
    console.log(y); // ReferenceError: y is not defined
    

    b. λ ‰μ‹œμ»¬ μŠ€μ½”ν•‘(Lexical scoping):

    ν•¨μˆ˜λ₯Ό 처음 μ„ μ–Έν•˜λŠ” μˆœκ°„μ— ν•¨μˆ˜ λ‚΄λΆ€μ˜ λ³€μˆ˜λŠ” **자기 μŠ€μ½”ν”„λ‘œλΆ€ν„° κ°€μž₯ κ°€κΉŒμš΄ κ³³(μƒμœ„ λ²”μœ„)**에 μžˆλŠ” λ³€μˆ˜λ₯Ό 계속 μ°Έμ‘°ν•˜κ²Œ λœλ‹€.

    var number = 1234
    
    function printNumber() {
      console.log(number);
    }
    
    function wrapper() {
      var number = 4321
      printNumber();
    }
    wrapper(); //1234
    

    c. μŠ€μ½”ν”„ 체인(Scope chain):

    μŠ€μ½”ν”„ Aμ•ˆμ— μŠ€μ½”ν”„ B, μŠ€μ½”ν”„ Bμ•ˆμ— μŠ€μ½”ν”„ C ← μ΄λ ‡κ²Œ 체인 ν˜•νƒœμ˜ μŠ€μ½”ν”„ ꡬ쑰λ₯Ό μ§€μΉ­ν•˜λŠ”λ°, κ°€μž₯ μ΄λ„ˆ μŠ€μ½”ν”„μ—μ„œ μ•„μš°ν„° μŠ€μ½”ν”„ λ³€μˆ˜ μ°Έμ‘° μ‹œ μ•ˆμ—μ„œ → λ°–μœΌλ‘œ 검색을 ν•˜κ²Œ λœλ‹€.

     

    πŸ‹ ν΄λ‘œμ Έ?


    클둜져의 어원인 closedλŠ”, λ‹«ν˜€μžˆλ‹€, 즉 자유 λ³€μˆ˜κ°€ ν•¨μˆ˜μ— λ‹«ν˜€μžˆλ‹€λŠ” 의미둜 μ“°μž…λ‹ˆλ‹€.

    ν΄λ‘œμ ΈλŠ” ν˜„μƒμ„ μ§€μΉ­ν•œλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. (이 ν˜„μƒμ΄ λ‚˜νƒ€λ‚˜λŠ” ν•¨μˆ˜λ₯Ό 클둜져 ν•¨μˆ˜λΌ λΆ€λ₯΄κΈ°λ„함.)

    μžλ°”μŠ€ν¬λ¦½νŠΈ μ—”μ§„ λ‚΄μ—μ„œ λŒμ•„λ‹€λ‹ˆλŠ” 가비지컬렉터가 참쑰되고 μžˆμ§€ μ•Šμ€ λ³€μˆ˜λ“€μ„ μˆ˜μ§‘ & μ‚­μ œλ₯Ό ν•˜κ³ ,

    κ·Έλ ‡μ§€ μ•Šκ³  참쑰되고 μžˆλŠ” λ³€μˆ˜λ“€μ„ μˆ˜μ§‘ λŒ€μƒμ—μ„œ μ œμ™Έκ°€ λ©λ‹ˆλ‹€.

    그런데 λ§Žμ€ κ²½μš°λ“€ μ€‘μ—μ„œ μ•„μš°ν„°ν•¨μˆ˜κ°€ μ’…λ£Œλ˜λ”λΌλ„ μ΄λ„ˆν•¨μˆ˜κ°€ μ•„μš°ν„°ν•¨μˆ˜μ˜ λ³€μˆ˜λ₯Ό 계속 μ°Έμ‘°ν•˜κ³  μžˆλŠ” 경우

    κ°€λΉ„μ§€μ»¬λ ‰ν„°μ˜ μˆ˜μ§‘ λŒ€μƒμ—μ„œ μ œμ™Έλ˜μ–΄ 접근이 κ°€λŠ₯ν•΄μ§€λŠ”λ°, 이 ν˜„μƒ 자체λ₯Ό 클둜져라 λΆ€λ¦…λ‹ˆλ‹€

    const counter = function() { // outer ν•¨μˆ˜
      let count = 0;
      function changeCount(number) { // inner ν•¨μˆ˜ 
        count += number;
      }
      return {
        increase: function() { // 더 inner ν•¨μˆ˜
          changeCount(1);
        },
        decrease: function() {
          changeCount(-1);
        },
        show: function() {
          alert(count);
        }
      }
    };
    
    const counterClosure = counter(); 
    // μ•„λž˜ λͺ¨λ“  λ©”μ†Œλ“œλŠ” μ•„μš°ν„° ν•¨μˆ˜μ˜ λ³€μˆ˜λ₯Ό μ°Έμ‘°ν•˜λ―€λ‘œ 클둜져 ν•¨μˆ˜λΌ λΆ€λ₯Ό 수 μžˆμŠ΅λ‹ˆλ‹€ 
    counterClosure.increase();
    counterClosure.show(); // 1
    counterClosure.decrease();
    counterClosure.show(); // 0
    

    클둜져 ν•¨μˆ˜μ™€ ν•¨κ»˜ 잘 λ“±μž₯ν•˜λŠ” “컀링 (Currying)”μ΄λΌλŠ” κ°œλ…μ΄ μžˆμŠ΅λ‹ˆλ‹€. 인자λ₯Ό μ—¬λŸ¬κ°œ ν•„μš”λ‘œν•˜μ§€λ§Œ λͺ¨λ‘ ν•œλ²ˆμ— λ°›μ•„μ˜€μ§€ λͺ»ν•˜λŠ” 경우, 클둜져 효과λ₯Ό μ΄μš©ν•΄μ„œ μ™ΈλΆ€ ν•¨μˆ˜ λ³€μˆ˜μ˜ 값을 κ³ μ •μ‹œν‚¨ ν›„ νŠΉμ • 인자λ₯Ό μž¬μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

    function firstRank(a){
        return function secondRank(b){
            return function thirdRank(c){
                return {"1λ“±":a, "2λ“±": b, "3λ“±": c}
            }
        }
    }
    
    let secondRank = firstRank("juyeon")
    let thirdRank = secondRank("songkang")
    let result = thirdRank("miumiu")
    console.log(result)
    

     

Designed by Tistory.