현재까지 이어진 상황으로서,

하나의 컴포넌트가 state 를 가질 수 있게 만들어 두었다.

하지만, 상위 컴포넌트의 state 가 하위 컴포넌트의 props 가 될 수 있다.

이 때, state, setState() 의 메서드는 EventTarget 으로부터 파생하였다.


Working File : useState.js


class CustomEventTarget extends EventTarget {
    constructor(secretValue) {
        super();
        this._secret = secretValue;
    }

    setSecret = (newSecret) => {
        this._secret = newSecret;
    }

    getSecret = () => {
        return this._secret;
    }

}

const useState = (value) => {
    const customEventTarget = new CustomEventTarget(value);


    return [() => customEventTarget.getSecret(), customEventTarget.setSecret];
}

window.useState = useState;

이는 튜플의 형식으로 반환하는데,

리액트의 상태 반환 메서드가 배열로 받는 것을 감안하여 개조하였다.


하지만, 개조한 위의 CustomEventTarget 클래스는 단순히 값의 저장과 반환에 초점이 맞춰져 있으며,

값의 변화 시 렌더링 트리거에 어떠한 영향도 끼치지 않는다.


여기서 넣어야 할 기능은, 해당 CustomEventTarget 의 값이 변동되었을 때,

현재 요소 혹은 부모 요소에 접근하여, innerText 혹은 innerHTML 을 바꿀 수 있게 만드는 것이다.

이 때, 단순 텍스트와 오브젝트의 차이를 어떻게 메꿀 것인지, 어떻게 공통화 시킬 건지에 초점을 맞춰야 한다.


지금까지, 커스텀 엘리먼트 혹은 일반 엘리먼트 클래스 컴포넌트에서 사용하는 방식은 다음과 같다 :

class InitComponent extends HTMLElement {
    constructor(){
        super();

        this.state;
        this.setState;
        // 배열 비구조화 방식 
        [this.state, this.setState] = useState(1);
    }

    connectedCallback(){
        // 브라우저 DOM 에 "실제로" 연결되면 호출, 실행됨.
    }

    disconnectedCallback(){
        // 브라우저 DOM 에서 연결이 끊어지면 호출, 실행됨.
    }

    adoptedCallback(){
        // 새로운 document 로 이동되었을 때 마다 호출됨.
        // 부모 트리가 바뀌면 실행되지 않을까? - 애매함.
    }

    attributeChangedCallback(name, oldValue, newValue){
        // 커스텀 컴포넌트에서 감지하기로 선언된 attribute 가 변경되면 실행됨.
        // <init-component number="1"> 에서 number 속성을 의미.
        // this.setAttribute("number", "2") 에서 number 속성을 의미
    }

    // 이 커스텀 컴포넌트의 "number" 속성 변화를 감지한다는 선언.
    static observedAttributes = ["number"];
    // static get observedAttributes() { return ["number"] } 과 동일.
}