React당
React - 스파게티코드 지양을 위한 Component 구성 방법
이히당
2024. 2. 17. 14:12
목표 : 반복되는 코드는 컴포넌트로 따로빼는것이 다방면으로 효율적이다.
하나의 예시로 테이블안에 들어갈 아이템들은 반복되는 것이기에 하나씩 다 구현하는 것은 정말 말도안된다.
보통 이런 경우에는 map함수를 사용해 테이블 안에 들어갈 데이터를 적절하게 조작하여 보여준다.
예시코드를 보자
<tbody>
{isLoading ? (
<tr>
<td colSpan="3">Is Loading</td>
</tr> ) : !study || study.length === 0 ? (
<tr>
<td colSpan="5"></td>
</tr> ) : (
<>
{study.map((todoItem, index) => (
<tr key={todoItem.id} className="border-b border-black">
{/*투두 완료 유무 + 완료 체크 기능*/}
<td className="p-3 text-sm text-center">
<span onClick={() =>
handleCheckbox(todoItem.id, todoItem.study_completed)
}
className={`p-1.5 text-xs font-medium tracking-wider rounded-md ${
todoItem.study_completed ? "bg-green-300" : "bg-red-300"
}`}
>
{todoItem.study_completed ? "Done" : "Incomplete"}
</span>
</td> {/*투두 내용*/}
<td className="p-3 text-sm" title={todoItem.id}>
{todoItem.study_todo}
</td>
{/*공부한 시간*/}
<td className="p-3 text-sm font-medium">
{todoItem.study_time}
</td>
{/*수정 및 삭제*/}
<td className="p-3 text-sm font-medium grid grid-flow-col items-center mt-5">
<span> <label htmlFor="my-modal">
<MdEditNote onClick={() => setEditText(todoItem)}
className="text-xl cursor-pointer"
/>
</label> </span> <span className="text-xl cursor-pointer">
<MdOutlineDeleteOutline onClick={() => handleDelete(todoItem.id)}
/>
</span> </td> <td className="p-3 text-sm" title={todoItem.id}>
<FaRegCheckCircle /> </td> </tr> ))}
</>
)}
</tbody>
isLoading변수는 데이터가 제대로 넘어오기 전까지의 처리를 도와준다.
데이터가 넘어오는 동안에도 사용자에게 화면을 보여주어야하기 때문에 추가했다.
데이터가 잘 넘어오면 map함수가 실행된다.
물론 이 코드도 모든 테이블 아이템을 일일이 하드코딩하지 않았기에 괜찮다고 볼 수 있으나, 컴포넌트화를 하면 더욱 간결하고 직관적으로 구성할 수 있다.
이제 컴포넌트로 빼보자.
import React from "react";
import {
MdOutlineDeleteOutline,
MdEditNote,
MdOutlineCheckBox,
MdOutlineCheckBoxOutlineBlank,
} from "react-icons/md";
import { FaRegCheckCircle, FaCheck } from "react-icons/fa";
import { RiCalendarTodoFill } from "react-icons/ri";
import { RxLapTimer } from "react-icons/rx";
const TodoItem = ({ todoItem, handleCheckbox, handleDelete, setEditText }) => {
return (
<tr key={todoItem.id} className="border-b border-black">
{/*투두 완료 유무 + 완료 체크 기능*/}
<td className="p-3 text-sm text-center">
<span onClick={() => handleCheckbox(todoItem.id, todoItem.study_completed)}
className={`p-1.5 text-xs font-medium tracking-wider rounded-md ${
todoItem.study_completed ? "bg-green-300" : "bg-red-300"
}`}
>
{todoItem.study_completed ? "Done" : "Incomplete"}
</span>
</td> {/*투두 내용*/}
<td className="p-3 text-sm" title={todoItem.id}>
{todoItem.study_todo}
</td>
{/*공부한 시간*/}
<td className="p-3 text-sm font-medium">{todoItem.study_time}</td>
{/*수정 및 삭제*/}
<td className="p-3 text-sm font-medium grid grid-flow-col items-center mt-5">
<span> <label htmlFor="my-modal">
<MdEditNote onClick={() => setEditText(todoItem)}
className="text-xl cursor-pointer"
/>
</label> </span> <span className="text-xl cursor-pointer">
<MdOutlineDeleteOutline onClick={() => handleDelete(todoItem.id)} />
</span> </td> <td className="p-3 text-sm" title={todoItem.id}>
<FaRegCheckCircle /> </td> </tr> );
};
export default TodoItem;
일단 이렇게 TodoItem이라는 컴포넌트를 새로이 만들었다.
이제 이 컴포넌트를 테이블에 적용하면 된다.
import TodoItem from './TodoItem';
// Table 컴포넌트 내부에서 TodoItem 컴포넌트 사용
{study.map((todoItem, index) => (
<TodoItem
key={index}
todoItem={todoItem}
handleCheckbox={handleCheckbox}
handleDelete={handleDelete}
setEditText={setEditText}
/>
))}
코드가 훨씬 간결해졌다.
여기서 이제 item에 들어갈 내용을 수정하고 싶으면 해당 컴포넌트 파일안에서 수정해주면 되기 때문에 상당히 직관적이다!
앞으로도 깔끔하고 이해하기 쉬운 코드를 짜기위해 노력해보자><
끗!
728x90