전체 글
디바운스와 쓰로틀
단시간에 많은 양의 이벤트가 발생하면 해당 이벤트핸들러가 너무 많이 실행되서 성능상의 문제가 발생할 수 있다. 디바운스와 쓰로틀을 활용해 이러한 문제를 해결할 수 있다. 디바운스 단기간에 많은 양의 이벤트가 발생할 때 마지막 이벤트에서만 (사용자 조작이 끝났을 때) 콜백 함수를 실행시킨다. let timer document.addEventListener('scroll', () => { if(timer) clearTimeout(timer) timer = setTimeout(() => { console.log('마지막에만 실행!) },400) }) 활용 사용자가 회원가입 할 때 아이디 중복체크를 자동적으로 해주는 경우가 있다. 사용자가 입력할 때 input에 change 콜백을 줘서 서버에 중복체크 요청을 ..
7. 정리 - 끝
1) 얻은 점들 ㄱ. 리액트에 좀 더 능숙해졌다. HOC, useReducer, context, useMemo, useCallback, 커스텀 훅, 컴포넌트 합성, 상태 관리 등등 ㄴ. Konva 라이브러리의 사용법을 익혔다. 추후 canvas 태그를 다뤄야할 때 유용하게 사용할 수 있을 것이다. ㄷ. 편집기, 저작도구 제작 경험을 쌓았다. 보편적인 웹사이트 개발과는 다른 경험이었다. 사용자의 행동들을 먼저 정의하고 그에 따라 개발하면서 많이 어려웠지만 추후 다른 편집기, 저작도구를 개발할 때 큰 도움이 될 것 같다. ㄹ. 프로젝트 회고를 처음으로 작성해보면서 내가 개발한 핵심 로직들을 리뷰하고 아쉬운 점들, 보완해야할 점들을 알 수 있었다. 앞으로도 프로젝트 회고는 꼭 작성해야겠다. ㅁ. 가독성 좋고 ..
6. 개발 - 뒤로가기(작업 취소), 앞으로 가기(복구) Z-index 조정 기능
1) 뒤로 가기(작업 취소), 앞으로 가기(복구) 뒤로 가기, 앞으로 가기 기능을 구현하기 위해서 back, front 2개의 스택을 만들었다. back 스택은 작업 실행 전 상태들을 담아놓고, front 스택은 앞으로 가기를 실행했을 때 현재 상태, 즉 복구되기전 상태들을 담아 놓았다. 각 스택에는 편집기의 배경, 이미지, 텍스트 정보가 들어간다. (nodes, background) 매 작업(ex: 배경색 변경, 노드 속성 변경 등)을 실행할 때마다 현재 상태와 이전 상태를 저장했다. (saveHistory, saveNow 메소드 실행) 즉 작업전 상태가 back 스택에 쌓이고 현재 상태는 nowState라는 변수에 담았다. 또, front 스택을 비워서 뒤로 가기 후 다른 작업을 실행할 시 앞으로 가..
5. 개발 - 상태 관리 리팩토링 - useReducer
1) 기존 상태 관리 - useState 기존에는 노드들(텍스트, 이미지)의 상태를 useState를 활용해서 상태 관리했다. const [nodes, setNodes] = useState([]) 이미지 편집기에서 특정 노드의 속성을 변경하는 경우가 많은데, 이런 경우에 특정 노드를 id를 통해서 찾고 걔의 속성을 변경하는 식의 코드가 들어가야 한다. immer을 사용해서 객체, 배열의 상태 변경을 쉽게 해도 중복되는 코드의 양이 너무 많았다. setNodes(state, draft => { const target = draft.find(node => node.id === targetId) target[property] = newProperty }) 이런 코드들이 많은 곳에 중복으로 들어갔다. 2) 변경..
Portal
Portal은 부모 컴포넌트의 DOM 계층 구조 바깥에 있는 DOM 노드로 자식을 렌더링하는 최고의 방법을 제공한다. - 공식문서 활용 모달을 구현할 때 유용하게 활용할 수 있다. 모달을 구현 시 제일 까다로운 부분은 z-index 설정이다. z-index는 부모 안에서만 적용되기 때문에 다른 컴포넌트가 z-index가 더 높은 경우 모달이 해당 컴포넌트에 가린다거나 하는 문제가 발생한다. 그렇기 때문에 최상위 컴포넌트에 조건부 렌더링으로 모달을 달아놓고 redux로 해당 상태를 관리해서 모달을 구현하는 식으로 사용을 했었다. {...생략} {isModalOpen && } 하지만 이렇게 구현했을 때는 많은 문제점이 있다. 1) 모달에 정보를 줄 때 redux를 활용함 - 이는 redux의 본래 취지(많은..
커스텀 훅 적용하기 - 팝업(모달)
커스텀 훅으로 컴포넌트 로직을 함수로 뽑아내어 재사용할 수 있다. - 공식 문서 예를 들어 상태 변수중에 컴포넌트가 마운트되고 data를 fetch해서 useEffect에서 상태값을 변경해줘야 하는 경우에 사용할 수 있다. 적용 현재 진행하고 있는 프로젝트에서, 많은 페이지에서 검색 필터 팝업을 공통적으로 활용하고 있다. 현재 검색 필터 팝업은 외부를 클릭했을 때 팝업창이 닫히지 않는 문제가 있어서, PM님이 이 부분을 해결해달라고 했다. 기존의 로직은 컴포넌트에서 열림 상태를 관리한다. isOpen && , 이런 식으로 버튼 눌렀을때 isOpen을 true로 만들고 팝업이 뜨게 하는 로직이다. 이 팝업창의 외부를 클릭시 닫히게 하기 위해서 2가지 방법을 고려했다. 1) 외부에 투명배경의 viewport..
4. 개발 - 편집기 주 화면 구현, 배경, 노드(이미지, 텍스트) 추가, 편집 기능
1) 화면 // 2) 배경 {nodes & nodes.map(node => } // 3) 노드 Konva의 Stage와 Layer를 활용해서 편집기 화면을 구성했다. 회고 2.의 레이아웃의 주 화면이다. 2) 배경 배경은 주 화면과 똑같은 크기의 Img 오브젝트를 배치해서 해당 오브젝트의 색을 변경하거나, 이미지를 삽입해 배경으로 쓸 수 있게 했다. Konva는 오브젝트들을 순서대로 그린다. 즉, 가 맨 앞에 위치해 있기 때문에 다른 노드들보다 뒤에 있어서 배경처럼 딱 보이게 된다. 회고 3.의 background 속성을 배경에 {...background}로 뿌려줘서 속성들을 반영하게 했다. 3) 노드 노드들은 속성을 에 뿌려준다. 이 노드는 Konva에서 제공해주는 것이 아니고 내가 만들었다. node..
3. 개발 - 기본 구조
1) 상태 관리 최상위 컴포넌트에서 배경화면과 텍스트, 이미지의 상태를 관리했다. 그리고 최상위 컴포넌트의 상태를 React Context를 활용해서 하위 컴포넌트에서 useContext로 활용할 수 있게 했다. const [background, setBackground] = useState(null) const [nodes, setNodes] = useState([]) return ( /// ...생략 ) 2) 컴포넌트 나누기 기능, 레이아웃을 기반으로 컴포넌트를 나눴다. 3) 보완할 점 ImageEditorContext 하나에 모든 상태들을 다 담아서 하위 컴포넌트로 전달하는데, 이러면 문제점이 하위 컴포넌트에서 useContext()를 사용하면 imageEditorContext에 들어간 value중..