인프런 커뮤니티 질문&답변

hweejin_cha님의 프로필 이미지
hweejin_cha

작성한 질문수

시나브로 자바스크립트

02. 쇼핑몰 만들기 Part 3 - (4 of 5) Virtual DOM

reactivity.js 를 proxy로 수정 후 오류

해결된 질문

작성

·

380

·

수정됨

0

어려워서 겨우 따라가고 있는 학생입니다!

현재 02.쇼핑몰만들기3(4/5) 수강중인데요

reactivity.js 를 proxy로 수정 후 나오는 에러는 알아서 해결하라고 미션을 주셨지만.. 도통 어떻게 해결해야 할지 모르겠습니다.

counter.js의 getTotalCount, getCountByProductId 함수 내부의 getCountMap()을 어떻게 수정하면 될지 힌트라도 요청드립니다!

 

===========================

현재 이렇게 수정했는데, 각 물품 갯수에는 undefined가 뜨고 장바구니 토탈 갯수만 나오고 있습니다.

첫 클릭만 undefined고 이후는 숫자가 증가하는데 해당 처리를 어떻게 해야 할까요..?

    const getTotalCount = () => {
        let count = 0;
        Object.values(countMap).forEach((number) => {
          count += number;
        });
        return count;
    };

    const getCountByProductId = ({ productId }) => {
        return countMap[productId] || 0;
    };
export function bindReactiveState({
    name, defaultValue
}){
    if (typeof defaultValue !== 'object') {
        throw new Error("bindReactiveState supports only object as default value.");
    }

    let value = new Proxy(defaultValue, {
        get(target, prop) {
            return target[prop];
        },
        set(target, prop, newValue) {
            const elements = Array.from(
                document.querySelectorAll(
                    `[data-subscribe-to='${name}'][data-subscription-path='${prop}']`
                )
            );
            elements.forEach(element => {
                if(element.tagName === 'INPUT') {
                    element.value = newValue[prop];
                } else {
                    element.innerHTML = newValue[prop];
                }
            });

            // target[prop] = newValue;
            return Reflect.set(target, prop, newValue);
        }
    });

    return value;
}

 

 

답변 2

2

안녕하세요, 인프런 AI 인턴입니다.

hweejin_cha님의 질문에 답변드리겠습니다.

우선 hweejin_cha님께서 reactivity.js 파일을 Proxy를 사용하여 reactivity 제공자를 구현하고 계신 것으로 보입니다.

문제는 set 트랩에서 target[prop]에 값을 할당할 때, newValue[prop]이 아니라 단순히 newValue를 할당해야 한다는 점입니다. 현재 코드에서는 newValue 객체 내부의 특정 프로퍼티 값을 찾으려고 하고 있어서 undefined가 될 가능성이 높습니다.

수정이 필요한 부분은 아래와 같습니다.

set(target, prop, newValue) {
    const elements = Array.from(
        document.querySelectorAll(
            `[data-subscribe-to='${name}'][data-subscription-path='${prop}']`
        )
    );
    elements.forEach(element => {
        if(element.tagName === 'INPUT') {
            // 기존: element.value = newValue[prop];
            element.value = newValue; // 수정 필요
        } else {
            // 기존: element.innerHTML = newValue[prop];
            element.innerHTML = newValue; // 수정 필요
        }
    });

    // target[prop] = newValue;
    return Reflect.set(target, prop, newValue);
}

Proxy의 set 트랩 내에서 newValue[prop] 대신 newValue를 할당하면 각 바인딩된 엘리먼트에 새로운 값이 제대로 반영될 것입니다.

또한 getTotalCountgetCountByProductId 함수에서는 countMap 객체의 참조 방법이 Proxy에 의해 변경된 방식에 맞춰져 있는지 확인해야 합니다. 이 부분은 제공된 코드만으로는 정확한 해결책을 제시하기 어렵지만, countMap의 Proxy 혹은 기존 객체 참조 방식에 맞춰 접근하여 적절한 값을 얻어야 할 것입니다.

문제가 해결되지 않는 경우, 해당 강좌의 Q&A 섹션에 질문을 남기거나 혹은 원하는 부분에 대한 더 자세한 설명을 강사님께 요청해 보시는 것이 좋을 것 같습니다.

시도해보시고 추후에도 문제가 지속된다면 언제든 추가로 질문해주세요.

감사합니다.

hweejin_cha님의 프로필 이미지
hweejin_cha
질문자

위 코드도 잘 작동합니다 감사합니다!!

이은재님의 프로필 이미지
이은재
지식공유자

오 지금 보니 AI 인턴님께서 newValue[prop] 대신 newValue 할당해야 한다는 걸 아주 잘 짚어주셨네요! 잘 했어요 AI 인턴님!

1

이은재님의 프로필 이미지
이은재
지식공유자

안녕하세요! 답변이 늦어져 죄송합니다.

 

일단 영상에서 마무리되었던 버전 기준으로 두 가지 버그 수정을 한 후에 작동하는 걸 볼 수 있었는데요. 우선 돌아가는 코드는 다음과 같습니다:

https://github.com/eunjae-lee/sinabro-js/pull/15

 

  1. Proxy 의 set 함수에서 값을 설정하는데 성공했다면 true 를 리턴해야 해요. 영상에서는 그 부분이 없었습니다.

  2. 1까지 했으면 상품을 + 눌렀을 때 우측 상단의 카트 수량은 업데이트 되는데, 해당 상품의 수량은 undefined 가 되는 상황을 보실 수 있을 거에요. 생각을 해보면, 카트 수량은 업데이트 된다.. 그러면 proxy 자체가 완전히 망가진 건 아닌 거겠죠? 그런데 해당 상품의 수량이 undefined 다.. 그러면 그 관련된 어딘가를 살펴봐야 할 거에요. 해당 상품의 수량을 업데이트 해주는 건, 이 버전에서는 proxy 의 set 함수 내에서 하도록 변경했잖아요? elements 를 forEach 돌면서. 거기를 들여다보니, 제가 이전 구현에서 복붙하면서 newValue[prop] 으로 가져왔었는데, 사실은 proxy 버전에서는 newValue 라고만 적었어야 했어요.

 

살펴보시고 이해 안가시는 부분 있으면 또 알려주세요 🙂

hweejin_cha님의 프로필 이미지
hweejin_cha
질문자

작동 잘됩니다 >< 감사합니다!!

hweejin_cha님의 프로필 이미지
hweejin_cha

작성한 질문수

질문하기