프로젝트를 진행하면서 무엇이 좋은 코드이고, 어떻게 하면 좋은 코드인지,아닌지 알 수 있을까를 계속 생각하게 되는 것 같습니다.
컴포넌트가 하나의 일을 하고, 변경에 유연해야 하는 것이 이상적이지만,
막상 제가 작성한 코드를 보면 변경에 유연하게 대응할 수 있는지 의문이 듭니다.
실제로 제가 최근에 작성한 컴포넌튼데, 너무 많은 일을 하고 있다는 느낌도 들고
(아래 코드입니다…),
이걸 재사용 할 수 있을까? 라는 질문에 스스로 ‘아니오’..라고 대답했던 것 같습니다.
사용자를 검색하는 역할도 있고, 클릭한 사용자의 상태를 갱신하고, 사용자 목록을 정렬하고,사용자 상세를 보여주는 것을 모두 한 컴포넌트에서 하고 있는데, 이를 어떻게 역할별로 분류할 수 있을까요..?
추가적으로 좋은 코드를 보는 눈을 기르려면 어떻게 해야 할까요?
책을 통해서 습득 할 수 있을까요? 리팩토링 2를 구매했는데, 해당 책을 읽어보셨다면 어떠셨는지도 궁금합니다!
import { useState, Suspense } from 'react' import { UserList, SearchBar } from '@/components' import { useGetAllResponseByReceiver } from '@/apis/hooks' import { NotFoundSearchUser, ReviewDetailAccordion } from '../../components' const AllResponseReviewByResponser = ({ surveyId }: { surveyId: string }) => { const [keyword, setKeyword] = useState('') const { data: responseByReceiver } = useGetAllResponseByReceiver({ surveyId, }) const [selectedUser, setSelectedUser] = useState<{ id: string name: string }>({ id: 'user', name: 'user', }) const [filteredUsers] = useState( responseByReceiver.data.receiverResponses.sort((a, b) => a.user.name.localeCompare(b.name), ), ) const handleChangeKeyword = (e: React.ChangeEvent<HTMLInputElement>) => { setKeyword(e.target.value) } const findUserBySearchKeyword = filteredUsers .map((value) => value.user) .filter((user) => user.name.trim().includes(keyword)) const shouldDisplayUserList = findUserBySearchKeyword.length !== 0 || responseByReceiver.data.receiverResponses.length === 0 return ( <div className="flex flex-col gap-5"> <SearchBar handleChangeKeyword={handleChangeKeyword} /> <div className="rounded-md border border-gray-200 bg-main-yellow text-black dark:border-gray-100 dark:bg-main-red-200 dark:text-white md:max-h-[24rem]"> <header className="flex items-center whitespace-pre-wrap rounded-t-md border-b border-b-gray-100 bg-main-yellow p-3 text-xs dark:border-b-gray-200 dark:bg-main-red-200 md:text-sm"> <span>수신자: </span> <span className="text-sub-blue dark:text-sub-skyblue"> {responseByReceiver.data.receiverResponses.length} </span> <span>명</span> </header> {shouldDisplayUserList ? ( <div className="max-h-80 overflow-auto"> <input type="checkbox" className="drawer-toggle" id="drawer-bottom" /> <UserList users={findUserBySearchKeyword} onClickUser={({ id, name }) => setSelectedUser({ id, name })} responserCount={filteredUsers.map( (value) => value.responserCount, )} /> <Suspense fallback={<div className="spinner"></div>}> <ReviewDetailAccordion reviewId={surveyId} receiverId={selectedUser.id} receiverName={selectedUser.name} /> </Suspense> </div> ) : ( <NotFoundSearchUser /> )} </div> </div> ) }