안녕하세요 웹 OB 이예림입니다..!
과제를 구현하던 중, 아래와 같이 각각의 함수로 필터링하는 방식이 매우 비효율적으로 느껴졌는데요,
🤔 필터링을 재사용한 것처럼, 동적으로 접근하는 방식이 있지 않을까? 라는 의문으로 해당 주제를 접하게 되었습니다.
const selectedGender = getSelectValue("sel_gender");
const selectedRole = getSelectValue("sel_role");
const inputName = getInputName();
const inputEnName = getInputValue("enNameInput");
const inputGithub = getInputValue("githubInput");
const inputWeek1 = getInputNumber("week1Input");
const inputWeek2 = getInputNumber("week2Input");
// 필터링
const filteredGender = filterGenderOrRole(
memberList,
"gender",
selectedGender
);
const filteredRole = filterGenderOrRole(filteredGender, "role", selectedRole);
const filteredName = filterName(filteredRole, inputName);
const filteredEnName = filterEnNameOrGit(filteredName, "enName", inputEnName);
const filteredGithub = filterEnNameOrGit(
filteredEnName,
"github",
inputGithub
);
const filteredWeek1 = filterWeek(filteredGithub, "week1", inputWeek1);
const filteredMembers = filterWeek(filteredWeek1, "week2", inputWeek2);
renderMemberList(filteredMembers); // 필터링된 리스트 렌더링
});
1. 객체로 필터 조건을 관리
: 이전 코드의 경우,
filterGenderOrRole(filteredGender, "role", selectedRole);
개별 필터 함수에 순서대로 (멤버리스트, 키값, 필터 값)을 전달했는데요, 이를 개별 함수로 처리하지 않고 filters 객체를 활용하여 필터 값을 하나로 묶었습니다. 객체화를 통해 필터 조건을 동적으로 처리할 수 있게 되었고, 더 이상 개별 함수에 필요한 인자를 넣지 않아도 되었습니다.
// 기존 개별 필터링에 **인자 3개씩 전달
// + id,class명 전달**해주던 코드 대체
const filters = {
gender: getSelectValue("sel_gender"),
role: getSelectValue("sel_role"),
name: getInputName(),
enName: getInputValue("enNameInput"),
github: getInputValue("githubInput"),
week1: getInputNumber("week1Input"),
week2: getInputNumber("week2Input")
};
2. Object.entries()를 사용한 동적 필터링
: 이전 코드에서는 각 필터 함수가 배열을 반복하면서 필터링을 적용했지만, Object.entries(filters) 를 사용하여 filters 객체의 모든 필터 조건을 순회하며 해당 필드와 필터 값을 비교할 수 있도록 구현하였습니다.
// 개별 필터링 대체
const filteredMembers = memberList.filter((member) =>
Object.entries(filters).every(([key, value]) =>
!value || member[key]?.toString().includes(value)
)
);
⭐️ Object.entries(filters)는 filters 객체의 key와 value를 반환하므로, member[key]로 해당 필드의 값을 동적으로 접근가능했습니다!
Object.entries()
: 키-값 쌍을 배열의 형태로 반환하는 메서드
: 객체 내부의 속성에 대해 쉽게 반복 작업을 가능하게 합니다.
const user = {
name: 'Mike',
age: 30,
gender: 'male',
}
// Object.entries(user)이 반환하는 배열
[
[ name, 'Mike'],
[ age, 30 ],
[ gender, 'male']
]
3. includes, 동적 속성 접근
member[key]?.toString().includes(value)
: 이전 코드에서는 각 필드를 명시적으로 지정했지만, 이를 동적으로 접근해보고자 했고 filters 객체의 키가 member[key]로 해당 필드에 동적 접근이 가능해졌습니다.
옵셔널 체이닝(?.)
: JS에서 안전하게 객체의 속성에 접근하기 위해 사용된다.
: 객체의 속성이 존재하지 않을 때 에러를 방지하고 undefined를 반환한다.
추가) 옵셔널 체이닝이 필요한 이유
4. 필터를 적용하지 않는 경우도 render.js에서 한번에 처리
(!value) 로 필터 미적용 케이스도 고려하였는데요,
이를 통해 각 유틸함수 상단에 작성했던 다음의 코드를 모두 제거할 수 있었습니다.
if (value === "") {
// return memberList;
}
최종 변경 코드
const filters = {
gender: getSelectValue("sel_gender"),
role: getSelectValue("sel_role"),
name: getInputName(),
enName: getInputValue("enNameInput"),
github: getInputValue("githubInput"),
week1: getInputNumber("week1Input"),
week2: getInputNumber("week2Input")
};
// 필터링 -> 필터가 존재하면 해당 값과 비교, 없으면 통과
const filteredMembers = memberList.filter((member) =>
Object.entries(filters).every(([key, value]) =>
!value || member[key]?.toString().includes(value)
)
);
renderMemberList(filteredMembers); // 필터링된 리스트 렌더링
});
+) 이후 공백, 대소문자 구분 로직 추가했습니다.. 총총...
'2주차' 카테고리의 다른 글
자바스크립트 - 함수 호스팅, 화살표 함수 (0) | 2024.10.29 |
---|---|
자바스크립트 reduce 메서드 알아보기 (0) | 2024.10.29 |
객체를 얼려주세요. Object.freeze() (0) | 2024.10.29 |
자바스크립트의 DOM 조작과 이벤트 리스너 바인딩의 순서, 그리고 이벤트 위임 (0) | 2024.10.28 |
[event.preventDefault()] 브라우저의 기본 동작을 막고,우리가 원하는 다른 동작을 넣을 수 있게 해주는 속성?! (0) | 2024.10.28 |