한달 두달 전에 짠 코드를 기능 추가, 수정의 이슈로 수정하는 경우가 빈번해졌는데, 내가 짠 코드여도 컴포넌트에 여러 로직이 뒤섞여 있어 코드의 흐름 파악을 하는데 있어 시간이 많이 걸렸다. 그래서 관심사별로 코드를 분리하여 컴포넌트의 덩치를 줄여보는 시도를 하게 되었다.
const Example = () => {
const [x, setX] = useState('')
const [y, setY] = useState('')
const [visible1, setVisible1] = useState(false)
const [visible2, setVisible2] = useState(false)
const { data, isLoading } = useQuery(['example', x, y], () => getSomething(x, y), {
select(data){
return data.map((element) => ({
...
}))
}
})
useEffect(() => {
document.title = x
},[x])
const handleXChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setX(e.target.value)
}
const handleYChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setY(e.target.value)
}
const handleOpenModal1Click = () => {
setVisible1(true)
}
const handleOpenModal2Click = () => {
setVisible2(true)
}
return (
<div>
<input value={x} onChange={handleXChange}/>
<input value={y} onChange={handleYChange}/>
<button onClick={handleOpenModal1Click}>open modal1</button>
<button onClick={handleOpenModal2Click}>open modal2</button>
{visible1 && <Modal1/>}
{visible2 && <Modal2/>}
</div>
)
}
Exampe.tsx
const Example = () => {
const { x, y, handleXChange, handleYChange } = useXY()
const { data } = useGetSomethingQuery(x, y)
return (
<div>
<input value={x} onChange={handleAChange}/>
<input value={y} onChange={handleBChange}/>
{data}
<ModalButtons/>
</div>
)
}
useXY.ts
const useXY = () => {
const [x, setX] = useState('')
const [y, setY] = useState('')
useEffect(() => {
document.title = x
},[x])
const handleXChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setX(e.target.value)
}
const handleYChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setY(e.target.value)
}
return { x, y, handleXChange, handleYChange }
}
export default useXY
useGetSomethingQuery.ts
const useGetSomethingQuery(x: string, y: string) => {
return useQuery(['example', x, y], () => getSomething(x, y), {
select(data){
return data.map((element) => ({
...
}))
}
})
}
export default useGetSomethingQuery
ModalButtons.tsx
const ModalButtons = () => {
const openModal = useSetAtom(modalsAtom)
const handleOpenModal1Click = () => {
openModal({
component: <Modal1/>,
props: {...},
})
}
const handleOpenModal2Click = () => {
openModal({
component: <Modal2/>,
props: {...},
})
}
return (
<button onClick={handleOpenModal1Click}>open modal1</button>
<button onClick={handleOpenModal2Click}>open modal2</button>
)
}
export default ModalButtons