useState, useEffect 등 다양한 내장 Hook 등을 조합하면 반복되는 로직을 분리해 Custom Hook을 작성할 수 있습니다.
import { useRef } from 'react';
import styled from 'styled-components/macro';
import CheckWrap from './DockContainer/CheckWrap';
import RangeWrap from './DockContainer/RangeWrap';
import { useOutsideClick } from '../../../../Util/useOutsideClick';
export default function Dock({ title, subTitle, type, list, range }) {
const contain = useRef();
const [isActive, setIsActive] = useOutsideClick(contain, false);
const handleActive = () => {
setIsActive(!isActive);
};
return (
<Container ref={contain} isActive={isActive}>
<Button onClick={handleActive} isActive={isActive}>
<p>{title}</p>
</Button>
{isActive && (
<Main>
<CheckWrap subTitle={subTitle} type={type} list={list} />
{range && <RangeWrap type={type} range={range} />}
</Main>
)}
</Container>
);
}
위의 Dock이라는 컴포넌트에 각각의 컨테이너 정보를 useRef()
를 통해 지정하여 해당 dom 정보를 useOutsideClick라는 커스텀 훅을 통해 감지하여 각각의 활성 여부를 체크하여 변경 처리하는 로직을 커스텀 훅으로 처리한 부분입니다.
import { useState, useEffect } from 'react';
export const useOutsideClick = (el, initialState) => {
const [isActive, setIsActive] = useState(initialState);
useEffect(() => {
const onClick = e => {
if (el.current !== null && !el.current.contains(e.target)) {
setIsActive(!isActive);
}
};
if (isActive) {
window.addEventListener('click', onClick);
}
return () => {
window.removeEventListener('click', onClick);
};
}, [isActive, el]);
return [isActive, setIsActive];
};