목록React (6)
신비한 개발사전
Konva는 HTML의 요소를 쓰기 쉽게 만들어주는 라이브러리다. 캔버스 안에 오브젝트 하나 그리려고 일일이 lineTo()와 moveTo()를 쓰지 않아도 되는 편리함을 제공한다. 관련 라이브러리는 Konva 외에도 Fabric.js, EaselJS 등 다양하지만 Konva를 선택한 이유는 리액트에서 사용할 때 깔끔해 보여서다. Fabric.js가 제일 인기있는 모양이지만 샘플 코드에서 useEffect를 쓰는 것을 보고 Konva를 써보기로 했다. * 리액트에서 Konva를 쓰려면 konva와 react-konva 둘 다 설치해야 한다. 기본 구조Konva의 캔버스는 컨테이너인 컴포넌트 안에 각 그림을 컴포넌트별로 나뉘는 구조를 갖고 있다. 캔버스 오브젝트는 이 와 의 영역 안에 구현한다. ..
react-calendar 라이브러리를 사용해 달력 컴포넌트를 만들 때, locale을 한국으로 설정하면 아래 이미지와 같이 모든 날짜 뒤에 "일"이 기본값으로 붙은 다소 난잡한 UI가 탄생하게 된다.import Calendar from "react-calendar"; 다행히도 달력에서 문자열을 지우는 건 매우 간단했다. react-calendar에서 제공하는 Calendar 컴포넌트는 CSS 스타일링은 물론 달력에 보이는 모든 텍스트를 커스터마이징할 수 있게 해준다. 일, 월, 연도는 각각 formatDay, formatMonth, formatYear prop으로 타겟 날짜의 string 값을 리턴하도록 함수를 전달하면 된다.import Calendar from "react-calendar"; date..
setInterval 함수를 사용해 카운트다운 타이머를 구현한 내 웹앱을 모바일에서 실행했을 때 치명적인 오류를 발견했다. 타이머를 실행한 상태에서 모바일 기기의 화면을 끄면, 화면이 꺼진 상태로 있는 동안에는 setInterval 함수도 멈춰버리는 것이다. 당연히 화면이 꺼진 상태에서도 setInterval 함수로 인해 카운트다운이 계속 진행되고 있을 거라고 생각했는데, 실제로는 타이머의 시간이 흐르지 않고 멈춘 상태였다가 모바일 기기의 화면이 다시 켜지면 그때 이어서 동작하도록 돼있었다. 찾아보니 모바일 기기에서는 배터리 수명 보존과 퍼포먼스 향상을 위해 setInterval, setTimeout과 같은 시간과 관련된 함수들을 스로틀링한다고 한다. 화면이 꺼져있는 동안에는 동작을 일시정지 시켰다가, ..
Material UI(MUI)는 구글의 디자인 프레임워크(Material Design)를 기준으로 하는 리액트 전용 UI 라이브러리다. 디자인 프레임워크는 간단히 말해서 하나의 표준으로 삼는 UI 스타일이라고 보면 된다.MUI는 Material Design을 따라 input, button, select처럼 웹에 흔히 쓰이는 구성 요소들을 컴포넌트화했기 때문에, 커스터마이징에만 익숙해지면 빠르고 간편하게 어디에서나 통용되는 UI 컴포넌트를 활용할 수 있다. MUI 컴포넌트를 내 사이트에 맞게 커스터마이징하는 방법은 다양한데, 그 중 커스텀 스타일을 개별적으로 적용하는 방법과 일괄로 적용하는 방법이 가장 보편적인 것으로 보인다. sx prop 사용 (개별 적용)각 MUI 컴포넌트에는 리액트 컴포넌트의 sty..
리액트 앱에서 setInterval처럼 자동으로 반복 실행되는 함수를 사용할 땐 리렌더링으로 인한 사이드이펙트를 걱정할 수밖에 없다. 내 앱은 1초마다 시간을 세는 타이머 앱인데, 부모 컴포넌트의 상태가 변하면 부모 컴포넌트는 물론 자식 컴포넌트까지 리렌더링되는 리액트의 특성 때문에 타이머와 상관없는 상태 값을 바꿔도 타이머가 리셋되는 현상이 있었다.// 부모 컴포넌트 - TimerContainerconst TimerContainer = () => { const [isRunning, setIsRunning] = useState(false); // 부모 컴포넌트의 상태 const intervalId = useRef(null); const startTimer = () => { setIsRunnin..
Intersection observer는 특정 DOM 요소가 트리거로 지정된 다른 DOM 요소와 만났을 때 함수를 실행시켜주는 웹 API 기능이다. 트리거로 지정한 DOM 요소가 있어야 제대로 작동하는 만큼, 이런저런 상태 변화 때문에 리렌더링이 자주 일어나는 리액트 프레임워크에서는 유의해야 할 pitfall이 있다. 사라진 타겟Intersection observer를 활용하기 위해서는 observer가 바라볼 타겟 요소가 필요한데, 리액트에서는 일반적으로 querySelector 대신 useRef 훅에 많이 의존하게 된다.const Component = () => { const ref = useRef(null); // DOM 요소를 저장할 변수 return 내 컴포넌트; // DOM 요소에 ref ..