⚡️ 선언적으로 유저 행동 이벤트 추적하기
최근에 B2C 업무에 투입되며 전반적인 앱 플로우와 곧 제가 하게 될 업무에 대해 설명을 들었습니다.
그중 data-driven 한 의사 결정을 위해 유저 이벤트 추적 툴을 도입한 상태였고,
정해주는 이벤트에 추적 기능을 붙이는 업무도 하게 될 것이라는 말씀을 들었습니다.
그러면서 예시 코드를 보여주셨는데 예시로 다음과 같이 버튼 클릭 이벤트 핸들러 함수 안에
추적 툴에서 제공한 함수를 이어붙인 모양이었습니다.
const handleClickSignUp = () => {
이벤트_추적();
// ~~~
회원가입();
// ~~~
}
이러한 방식은 하나의 함수에 두가지 이상의 기능이 담겨 가독성을 해치고 유지보수가 여러워 질 것이 뻔합니다.
그렇다면 기능을 분리하고 선언적으로 사용할 수 있도록 컴포넌트화를 하면 좋겠는데 순간 예전에 인상 깊게 봤던 글이 떠올랐습니다.
토스 프론트엔드 개발자 분이 토스 기술 블로그에 작성하신 글인데
그중에서도 위와 같은 방법을 비슷하게 구현해서 써먹을 수 있겠다 싶었습니다.
그런데 실제로 구현된 코드는 나와있지 않고 아이디어만 얻었을 뿐이어서
리액트의 새로운 기능을 찾아보며 개념을 비슷하게 따라 해봤습니다.
📌 Event 가로채기
우선 자식 요소의 이벤트를 가져다가 어떤 행동을 취하려면 부모 컴포넌트에서 그 이벤트를 사용할 수 있어야 합니다.
리액트에서는 자식 요소를 부모 요소에서 사용할 수 있고, 사용하는 방법은 다음과 같습니다.
type PropsType = {
children: React.ReactElement;
};
const ParentConponent = ({ children }: PropsType) => {
console.log("children => ", children);
return children;
};
export const ChildrenComponent = () => {
return (
<ParentConponent>
<button onClick={() => console.log("클릭 이벤트 발생")}>버튼</button>
</ParentConponent>
);
};
이 컴포넌트들이 렌더링 된 후 콘솔에 찍힌 children
은 다음과 같습니다.
자세히 들여다보면 children.props
안에 onClick()
함수가 존재하는 것을 확인할 수 있습니다.
const { onClick } = children.props;
그렇다는 것은 위와 같이 자식 요소에서 이벤트 함수를 꺼내 재정의 할 수 있다는 것을 의미합니다.
그럼 이제 재정의 한 함수를 children에 다시 적용해 주면 되겠죠?
📌 React.cloneElement()
React.cloneElement
함수는 React 라이브러리에서 제공하는 함수 중 하나로,
기존의 React 엘리먼트를 복제하면서 일부 속성을 수정하거나 새로운 속성을 추가하는 데 사용됩니다.
이 함수는 React 엘리먼트를 더 동적으로 조작하고 확장할 수 있는 방법을 제공합니다.
React.cloneElement(element, [props], [...children])
element
복제할 기존 React 엘리먼트입니다.props
(선택 사항)
새로운 속성 객체로, 기존 엘리먼트의 속성을 수정하거나 추가할 수 있습니다.children
(선택 사항)
새로운 자식 엘리먼트를 지정할 수 있습니다. 기존 엘리먼트의 자식 엘리먼트를 대체하거나 추가할 수 있습니다.
그럼 cloneElement를 이용해 자식 요소의 이벤트를 재정의하고 적용하는 코드는 다음과 같습니다.
import React, { cloneElement } from "react";
type PropsType = {
params: string;
children: React.ReactElement<{ onClick: () => void }>;
};
const ClickEventLogging = ({ params, children }: PropsType) => {
const overrideClickEvent = () => {
const { onClick } = children.props;
console.log(children);
console.log("Logging: ", params);
onClick();
};
return cloneElement(children, { onClick: overrideClickEvent });
};
export default function App() {
return (
<div>
<ClickEventLogging params="버튼 클릭">
<button onClick={() => console.log("버튼 클릭 이벤트 발생")}>
클릭 후 콘솔을 확인해 주세요
</button>
</ClickEventLogging>
</div>
);
}
이렇게 하면 간단하고 효율적으로 분리해 유저 이벤트를 재정의 할 수 있습니다.
또한 여기서 아주 조금만 수정한다면 효과적인 로깅과 유저 행동을 추적하는 컴포넌트를 제작할 수 있게 됩니다.
그럼 이번에 찾아본 내용들을 토대로 실제 서비스에 적용해 봐야겠습니다.
'React' 카테고리의 다른 글
[React/TypeScript] 절대경로 CRA 템플릿 npm 배포 (0) | 2023.09.11 |
---|---|
[React] ErrorBoundary를 통한 선언적인 에러 핸들링, react-query를 이용한 재호출 방법 (0) | 2023.09.04 |
[React, 사이드 프로젝트] 링모(LINGMO), 당신의 링크 모음 (0) | 2023.08.21 |
[React] SPA 사이드 프로젝트 검색 엔진 최적화(SEO) 끝장내기 (0) | 2023.08.13 |
[React] 스크롤 애니메이션, IntersectionObserver + styled-components (0) | 2023.08.06 |
댓글