-
JavaScript의 customElements에서 Proxy을 활용한 객체 변화 감지Frontend/JavaScript 2023. 3. 3. 14:13반응형
앞서 작성한 글을 완벽하게 숙지하고 사용하시다 보면 attribute 값을 업데이트 하는 과정에서 여러 의문이 들 것입니다.
??? :
observedAttributes()
와attributeChangedCallback()
으로 태그의 attribute 값이 바뀌는 것을 감지해주는건 알겠는데…??? : 여기에
render()
함수를 걸어두면 attribute값이 바뀔 때 렌더링도 자동으로 최신화해주는 것도 알겠는데..??? : attribute는 텍스트만 넘겨줄 수 있고, attribute를 감지하는 것이지 엘리먼트 내부의 상태값을 감지하는 것은 아니지 않나?
객체가 변했을 때 렌더링이 자동으로 일어나게 할 수 없을까?
customElements을 그렇게 만들어 보겠습니다.
class MyProxyElement extends HTMLElement { constructor() { super(); this.state = new Proxy({ value: 'init value' }, { set: (obj, prop, value) => { obj[prop] = value; console.log('나 바뀜!') this.render(); return true; }, }); this.render(); } render() { this.innerHTML = `현재 상태는? : ${this.state.value}`; } } export default MyProxyElement;
어떤 state를 Proxy로 작성하게 되면, 특정 상태를 감시할 수 있습니다.
Proxy 객체를 사용하면 어떤 객체의 작업을 가로채서 재정의를 할 수 있습니다.
이 객체에 대한 설명은 MDN이나 모던JS 문서에도 잘 나와있지만,
이 블로그에 있는 글도 다양한 사용법을 소개해줍니다.
위의 문서를 참고해보면 다음과 같은 해석이 가능합니다.
this.state에 어떤 객체
{ value: 'init value' }
를 감시 대상자로 지정하고, 그 객체가 특정한 어떤 행동을 했음을 감지했을 때, 다음 행동으로 동작하게 합니다.이 설명이 다소 복잡하여 좀 더 상세하게 예시를 들면
// 위 클래스의 생성자 내부를 가져온 것 입니다. this.state = new Proxy({ value: 'init value' }, { set: (obj, prop, value) => { obj[prop] = value; console.log('나 바뀜!') this.render(); return true; }, });
클래스 필드로 상태를 등록할 때, Proxy가 중간에 value를 가로채서 변화를 감지할 수 있습니다.
get 옵션을 준다면 값을 읽어들일 때, set 옵션을 준다면 값을 재정의할때 등 여러 상황의 이벤트를 감지할 수 있게 됩니다.
즉, 초기값으로 this.state.value는 ‘init value’를 가지게 될 것입니다.
하지만 이 객체는 그냥 객체가 아닌 Proxy 객체에 의해 감시를 받고 있게 됩니다.
바깥에서는 이 객체가 감시 받는 중인지 잘 모르겠지만요!
(감시라는 표현이 맞는지 모르겠지만 이해를 돕기 위해 이렇게 설명합니다.)
위에서 만든 클래스를 정의해주고
customElements.define('my-proxy', MyProxyElement);
html에서도 호출해봅니다.
<my-proxy id="myProxy"></my-proxy>
그리고 이 객체의 상태를 업데이트 하기 위한 버튼을 생성 해보겠습니다.
<button onclick="changeProxyState()">상태를 바꿔보자</button>
function changeProxyState() { const myProxy = document.getElementById('myProxy'); myProxy.state.value = 'new value' }
그리고 이 버튼을 눌러보면
현재 상태는? : init value
에서
현재 상태는? : new value
으로 스스로 바뀌는 것을 확인할 수 있습니다.
이 버튼은 그저 단순히 이 엘리먼트의 value 값을 수정했을 뿐인데, 왜 재렌더링이 됐을까요?
콘솔창도 열어보면, 버튼을 눌렀을 때
나 바뀜!
도 출력됨을 확인할 수 있습니다.즉, Proxy객체의 setter가 value 값이 새로 쓰일 때를 감지하여 재 렌더링을 유도했음을 확인할 수 있습니다.
꼭 위의 예제처럼 state를 직접 수정하지 않아도, 간접적으로 수정하면 그 값이 자동으로 변경되는 것을 확인할 수 있게 됩니다.
반응형'Frontend > JavaScript' 카테고리의 다른 글
코드의 가독성을 위해 필수로 알아야 할 .every()와 .some() (0) 2023.04.04 CustomEvent를 활용하여 customElements에 객체를 전달하는 방법 (0) 2023.03.27 JavaScript에서 customElements를 활용하여 독립적인 상태 관리하기 (2) 2023.03.01 .onsubmit과 .addEventListener의 차이 (0) 2023.02.27 JavaScript 클래스 문법은 어떻게 쓰는 것일까? (0) 2023.02.22