23.05.10
오늘 한 일
- 알고리즘 문제 풀이
- 바닐라 JS로 리액트 만들기 스터디 정리
- 저번 주차에 만들었던 VirtualDOM에서 render phase와 commit phase 분리 노션 링크
- 익스텐션 리팩토링
- 모달 켜질 때 뒷 배경의 스크롤바가 사라져 layout shift 되는 문제 수정
알고리즘 문제 풀이
배열을 특정 값으로 초기화 하는 방법
```js
Array(배열 길이).fill(채울 값);
// or
Array.from({length: 배열 길이}, () => 채울 값);
10진수를 2진수로 변경했을 때 n자리로 유지하고 싶을 때
(10진수).toString(2).padStart(n, '0');
2진수로 된 문자열에서 '0'이면 공백, '1'이면 '#'으로 변경
(2진수로 된 문자열).replace(/0/g, ' ').replace(/1/g, '#');
// or
(2진수로 된 문자열).replace(/0|1/g, (match) => match === '0' ? ' ' : '#');
`single vertical bar`?
```js
a|b
a와 b를 각각 2진수로 변환 후, 각 자리수를 비교하여 둘 중 하나라도 1이면 1, 아니면 0으로 변환해준다.
그럼 이 문제를 한 줄로 클리어할 수 있다!!
const solution = (n, a, b) =>
a.map((a, i) => (a | b[i]).toString(2).padStart(n, 0).replace(/0/g, ' ').replace(/1/g, '#'));
정규표현식과 single vertical bar
라는 개념을 알았다면 쉽게 풀 수 있는 문제였다.
익스텐션 리팩토링
기존에 useBodyScrollLock
hook을 만들어서 사용했었는데, 모달 켜질 때 뒷 배경의 스크롤바가 사라져 layout shift 되는 문제가 있었다.
이 문제를 해결하기 위해 Modal이 켜지면 useEffect로 스타일을 바꾸고, Modal이 꺼지면 다시 원래 스타일로 바꾸는 방식으로 해결했다.
useEffect(() => {
document.body.style.cssText = `
position: fixed;
top: -${window.scrollY}px;
overflow-y: scroll;
width: 100%;`;
return () => {
const scrollY = document.body.style.top;
document.body.style.cssText = '';
window.scrollTo(0, parseInt(scrollY || '0', 10) * -1);
};
}, []);
원래 Modal 컴포넌트에서는 isOpen
을 props로 받아서 구현했었는데, Modal 컴포넌트를 사용하는 쪽에서 isOpen
을 관리하도록 수정했다.
그리고 Content.js
에 Modal에 해당하는 코드를 ContentModal
이라는 컴포넌트로 분리했다. 이 컴포넌트에 위의 useEffect 부분을 넣어서 Modal이 켜질 때 스타일을 바꾸고, 꺼질 때 원래 스타일로 바꾸도록 했다.
<Portal elementId="modal">
{isModalOpen && (
<ContentModal
ref={modalRef}
onClick={event => {
if (event.target === modalRef.current) setIsModalOpen(false);
}}
assignmentList={assignmentList}
courseList={courseList}
handleRefresh={handleRefresh}
/>
)}
</Portal>
Filter 컴포넌트도 리팩토링했다.
기존 코드
<Filter
value={selectedCourse}
onChange={setSelectedCourse}
hasBorder={false}
maxWidth="300px"
<Filter.Header className="text-[18px] font-bold" name={selectedCourse.name} />
<Filter.Modal pos="left">
{courseList.map(course => (
<Filter.Item key={course.id} item={course}>
{course.name}
</Filter.Item>
))}
</Filter.Modal>
</Filter>
<div className="flex gap-[16px]">
<Filter value={sortType} onChange={setSortType}>
<Filter.Header name={sortType} />
<Filter.Modal>
<Filter.Item item="마감일 순">마감일 순</Filter.Item>
<Filter.Item item="최신 순">최신 순</Filter.Item>
</Filter.Modal>
</Filter>
<Filter value={statusType} onChange={setStatusType}>
<Filter.Header name={statusType} />
<Filter.Modal>
<Filter.Item item="진행중인 과제">진행중인 과제</Filter.Item>
<Filter.Item item="모든 과제">모든 과제</Filter.Item>
</Filter.Modal>
</Filter>
</div>
리팩토링 후
<Filter
value={selectedCourse}
onChange={setSelectedCourse}
hasBorder={false}
maxWidth="300px"
<Filter.Header className="text-[18px] font-bold" />
<Filter.Modal pos="left">
{courseList.map(course => (
<Filter.Item key={course.id} item={course} />
))}
</Filter.Modal>
</Filter>
<div className="flex gap-[16px]">
<Filter value={sortType} onChange={setSortType}>
<Filter.Header />
<Filter.Modal>
{sort.map(item => (
<Filter.Item key={item.id} item={item} />
))}
</Filter.Modal>
</Filter>
<Filter value={statusType} onChange={setStatusType}>
<Filter.Header />
<Filter.Modal>
{status.map(item => (
<Filter.Item key={item.id} item={item} />
))}
</Filter.Modal>
</Filter>
</div>
기존의 코드는 불필요하게 props를 넘겨준 것 같아서 Filter 컴포넌트를 리팩토링했다.
value
에 들어가는 타입은 다음과 같다.
type valueType = { name: string; [key: string]: any };
이렇게 함으로써 가독성 좋게 코드를 작성할 수 있었다.
해결 해야하는 이슈
필터 modal을 여러 개 켜고 하나의 필터를 선택했을 때 다른 필터가 적용되는 이슈가 있다.
아마도 handleChange
의 문제가 아닐까 싶다. 내일 빠르게 해결해야겠다.
앞으로 해야하는 것
- 동영상 과제를 보여주는 기능 추가
- 과제 테이블 위에 오름차순, 내림차순을 선택할 수 있도록 기능 추가
- github workflow로 CI/CD 구현
- 테스트 코드 작성
- 반응형 UI
내일 할 일
- 알고리즘 문제 풀이
- 바닐라 JS로 리액트 만들기 스터디 진행
- 익스텐션 개발
- nest.js 강의 듣기
- 쿠버네티스 강의
Kubernetes를 통한 클라우드 조정
듣기 - 학습공동체 보고서 작성 후 제출