리액트를 만들기 위해 필요한 문법과 패턴

1. 클로저(Closure)

클로저는 자바스크립트에서 매우 중요한 개념 중 하나.

React의 상태 관리 시스템은 클로저를 많이 활용함.

클로저는 함수가 외부 변수에 접근할 수 있게 해주며, React의 상태 업데이트에서 이러한 개념이 사용.

예시:


function createCounter() {
  let count = 0;
  return function() {
    count += 1;
    return count;
  };
}

const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2

이처럼 상태를 함수 내부에서 유지하면서 외부에서 접근하는 패턴은 React의 상태 관리 방식과 유사함.

디버깅 도구로 스코프를 확인하는 것을 추천.

2. 함수형 프로그래밍 패러다임

React는 함수형 프로그래밍 패러다임을 많이 차용.

순수 함수(pure function)불변성(immutability)고차 함수(higher-order function) 등이 중요한 역할.

  • 순수 함수: 입력에 의해서만 출력이 결정되고, 외부 상태를 변경하지 않는 함수.

  • 불변성: 상태 변경 시 객체를 직접 변경하는 대신, 새로운 객체를 반환함으로써 원본을 유지함.

  • 고차 함수: 함수를 인자로 받거나 함수를 반환하는 함수.

예시 (순수 함수와 불변성):

const increment = (count) => count + 1;
console.log(increment(0)); // 1

예시 (고차 함수):


//아래처럼 동작하는 withLogging 을 만들어보세요.
const add = (a, b) => a + b;
const addWithLogging = withLogging(add);
console.log(addWithLogging(2, 3)); 

//입력받은 arguments를 배열형태로 출력
//Arguments:  [2, 3]
function withLogging(fn) {
  return function(...args) {
    console.log('Arguments:', args);
    return fn(...args);
  };
}

3. store- view 관계 맺기 - Observer 패턴

Observer 패턴은 상태가 변경되었을 때 해당 변경을 구독하고 있는 객체들에게 자동으로 알려주는 패턴.

React의 상태 관리 시스템이나 Redux와 같은 상태 관리 라이브러리는 이 패턴을 사용.

이는 상태 변화에 따른 UI 업데이트를 처리하는데 핵심적임.

예시 (간단한 Observer 패턴):


class Observable {
  constructor() {
    this.subscribers = [];
  }

  subscribe(callback) {
    this.subscribers.push(callback);
  }

  notify(data) {
    this.subscribers.forEach((callback) => callback(data));
  }
}

const observable = new Observable();
observable.subscribe((data) => console.log('Subscriber 1:', data));
observable.subscribe((data) => console.log('Subscriber 2:', data));

observable.notify('State changed'); 
// Subscriber 1: State changed
// Subscriber 2: State changed

4. store- view 관계 맺기 -프록시(Proxy)와 Object.defineProperty

상태 변경을 감지하고 이에 따라 UI를 자동으로 업데이트해야 하는 방법이 유용,

이러한 상태 변화를 추적하는 데 Proxy 또는 Object.defineProperty가 사용될 수 있음.

Proxy 예시:

프록시는 객체의 동작을 가로채고 수정할 수 있는 기능을 제공함.

const target = {
  message: "Hello, World!"
};

const handler = {
  get: function(target, prop) {
    return prop in target ? target[prop] : "Property does not exist";
  },
  set: function(target, prop, value) {
    console.log(`Setting value ${value} to ${prop}`);
    target[prop] = value;
  }
};

const proxy = new Proxy(target, handler);

// 접근 시
console.log(proxy.message); // "Hello, World!"
console.log(proxy.nonexistent); // "Property does not exist"

// 값 설정 시
proxy.message = "Hello, Proxy!"; // "Setting value Hello, Proxy! to message"
console.log(proxy.message); // "Hello, Proxy!"

음,

사용자가 입력한 값을 모델의 속성에 반영하고,

모델이 업데이트되면 뷰를 자동으로 갱신하도록 할 때,

Proxy를 활용할 수 있을까? 🤔

target 이라는 부분이 모델?이 될 수도 있고, setter 에서 뷰를 렌더링하도록 하면?

Object.defineProperty 예시:

기존 객체의 속성에 대해 getter와 setter를 설정하여, 해당 속성에 접근하거나 수정할 때 동작을 제어할 수 있음.

const obj = {};
let value = 0;

Object.defineProperty(obj, 'count', {
  get() {
    return value;
  },
  set(newValue) {
    console.log(`Setting count to ${newValue}`);
    value = newValue;
  }
});

// 접근 시
console.log(obj.count); // 0

// 값 설정 시
obj.count = 5; // "Setting count to 5"
console.log(obj.count); // 5