Skip to content

Commit

Permalink
refactor: updateAttributes 함수 util 함수로 분리
Browse files Browse the repository at this point in the history
  • Loading branch information
9yurilee committed Dec 27, 2024
1 parent f95e4ea commit 75e26e1
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 56 deletions.
19 changes: 2 additions & 17 deletions src/lib/createElement.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { addEvent } from "./eventManager";
import { handleUpdateAttr } from "../utils";

export function createElement(vNode) {
// vNode가 null, undefined, boolean 면 빈 텍스트 노드를 반환.
Expand All @@ -24,24 +24,9 @@ export function createElement(vNode) {
// - vNode.type에 해당하는 요소를 생성
const element = document.createElement(vNode.type);
// - vNode.props의 속성들을 적용 (이벤트 리스너, className, 일반 속성 등 처리)
updateAttributes(element, vNode.props || {}); // props: { id: '' , ... }
handleUpdateAttr(element, vNode.props, {}); // props: { id: '' , ... }
// - vNode.children의 "각 자식"에 대해 createElement를 재귀 호출하여 추가
element.append(...vNode.children.map(createElement));

return element;
}

// vNode.props의 속성들을 적용. (이벤트 리스너, className, 일반 속성 등 처리)
function updateAttributes($el, props) {
Object.entries(props).forEach(([attr, value]) => {
if (attr.startsWith("on") && typeof value === "function") {
addEvent($el, attr.slice(2).toLowerCase(), value);
return;
} else if (attr === "className") {
$el.setAttribute("class", value);
return;
} else {
$el.setAttribute(attr, value);
}
});
}
41 changes: 2 additions & 39 deletions src/lib/updateElement.js
Original file line number Diff line number Diff line change
@@ -1,42 +1,5 @@
import { addEvent, removeEvent } from "./eventManager";
import { createElement } from "./createElement.js";

function updateAttributes(target, originNewProps, originOldProps) {
if (!originOldProps && !originNewProps) return;

const newProps = originNewProps || {};
const oldProps = originOldProps || {};

// 속성 제거 처리
Object.entries(oldProps).forEach(([attr, value]) => {
if (!newProps[attr]) {
if (attr.startsWith("on")) {
const eventType = attr.slice(2).toLowerCase();
removeEvent(target, eventType, value);
} else {
target?.removeAttribute(attr);
}
}
});

// 속성 추가/갱신 처리
Object.entries(newProps).forEach(([attr, value]) => {
if (oldProps[attr] !== value) {
if (attr.startsWith("on")) {
const eventType = attr.slice(2).toLowerCase();
//
if (typeof oldProps[attr] === "function") {
removeEvent(target, eventType, oldProps[attr]);
}
addEvent(target, eventType, value);
} else if (attr === "className") {
target.setAttribute("class", value);
} else {
target.setAttribute(attr, value);
}
}
});
}
import { handleUpdateAttr } from "../utils";

export function updateElement(parentElement, newNode, oldNode, index = 0) {
const currentNode = parentElement?.childNodes[index];
Expand Down Expand Up @@ -67,7 +30,7 @@ export function updateElement(parentElement, newNode, oldNode, index = 0) {
} else {
// 같은 타입의 노드 업데이트.
// 속성 업데이트.
updateAttributes(currentNode, newNode.props, oldNode.props);
handleUpdateAttr(currentNode, newNode.props, oldNode.props);

const oldChildren = oldNode.children?.length;
const newChildren = newNode.children?.length;
Expand Down
45 changes: 45 additions & 0 deletions src/utils/attrUtils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { addEvent, removeEvent } from "../lib/eventManager";

/**
* 요소의 속성과 이벤트를 업데이트합니다.
*
* @param {HTMLElement} element - 속성을 업데이트할 DOM 요소.
* @param {Object} oldProps - 이전 속성 객체.
* @param {Object} newProps - 새로운 속성 객체.
*/

export const handleUpdateAttr = (target, originNewProps, originOldProps) => {
if (!originOldProps && !originNewProps) return;

const newProps = originNewProps ?? {};
const oldProps = originOldProps ?? {};

// 속성 제거 처리
Object.entries(oldProps).forEach(([attr, value]) => {
if (!newProps[attr]) {
if (attr.startsWith("on")) {
const eventType = attr.slice(2).toLowerCase();
removeEvent(target, eventType, value);
} else {
target?.removeAttribute(attr);
}
}
});

// 속성 추가/갱신 처리
Object.entries(newProps).forEach(([attr, value]) => {
if (oldProps[attr] !== value) {
if (attr.startsWith("on") && typeof value === "function") {
const eventType = attr.slice(2).toLowerCase();

if (typeof oldProps[attr] === "function") {
removeEvent(target, eventType, oldProps[attr]);
}

addEvent(target, eventType, value);
} else {
target.setAttribute(attr === "className" ? "class" : attr, value);
}
}
});
};
1 change: 1 addition & 0 deletions src/utils/index.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from "./eventUtils";
export * from "./timeUtils";
export * from "./attrUtils";

0 comments on commit 75e26e1

Please sign in to comment.