-
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' 카테고리의 다른 글
IntersectionObserver를 활용한 element 감지 및 응용 (무한스크롤, 중간광고 예제 포함) (0) 2023.04.08 CustomEvent를 활용하여 customElements에 객체를 전달하는 방법 (0) 2023.03.27 JavaScript에서 customElements를 활용하여 독립적인 상태 관리하기 (2) 2023.03.01 .onsubmit과 .addEventListener의 차이 (0) 2023.02.27 JavaScript 클래스 문법은 어떻게 쓰는 것일까? (0) 2023.02.22