이 포스트는 https://javascript.plainenglish.io/decoupling-logic-from-ui-create-react-components-like-a-boss-7ebde91671c8 를 번역하였습니다. 논리 로직과 UI를 분리하면 컴포넌트를 더 쉽게 작성하고 테스트 할 수 있습니다.
이 포스트의 주 목적은 각 컴포넌트가 데이터, 오류처리, 로드 및 기타 필요한 논리에만 관심을 갖는 방식으로 새롭게 컴포넌트를 작성하도록 하는 것입니다.
중요한 이유
- 확장성: 실제로 컴포넌트에 대한 확장성이 뛰어납니다.
- 제거 가능성: 컴포넌트 삭제가 문제되지 않아야 하며, 주요 변경이나 회귀가 발생하지 않습니다.
- 이동성: 어디서나 동일한 API를 사용하는 프로젝트 간에 컴포넌트를 사용할 수 있습니다.
Hands-On
코드를 자세히 살펴보고, 리팩토링 전후의 2가지 예를 보여 드리겠습니다.
import React, { useMemo } from 'react';
import useAxios from 'axios-hooks';
const TodoList = () => {
const [{ data, loading, error }] = useAxios( `/`);
const todoItems = useMemo(
() => (data ? data.filter((item) => item.status === 'TODO') : []),
[data],
);
if (loading) return <div>Loading...</div>;
if (error) return <div>Error</div>;
return <div>{JSON.stringify(todoItems)}</div>;
};
export default TodoList;
위에서 볼 수 있듯이, axios를 사용하여 원격 API 구성을 통해 데이터를 요청하여 To-Do 목록을 구현하는 간단한 예제가 있습니다.
상태 = ToDo인 항목을 추출하는 간단한 계산을 할 수 있나요? 대답이 '예!' 라면 같은 페이지에 있다고 할 수 있습니다.
포스트 시작부분에서 설명 한 것처럼 우리의 임무는 UI 에서 논리를 분리하는 것이지만, 위 예에서는 동일한 JS 파일에 논리가 있으므로 임무를 달성하기 위해 수행해야 하는 작업을 살펴 보겠습니다.
import { useMemo } from 'react';
import useAxios from 'axios-hooks';
const useTodoList = () => {
const [{ data, loading, error }] = useAxios( `/`);
const todoItems = useMemo(
() => (data ? data.filter((item) => item.status === 'TODO') : []),
[data],
);
return [{ data, loading, error, todoItems }];
};
export default useTodoList;
보시다 시피, useTodoList
라고 불렀습니다. 이 Hook은 TodoList 컴포넌트의 로직을 포함해야 합니다. 파일에 UI가 없다는 것을 알 수 있는데, 이는 사용자가 지정한 커스텀 훅 (Custom Hook) 입니다.
import React from 'react';
import useTodoList from './useTodoList';
const TodoList = () => {
const [{ data, loading, error, todoItems }] = useTodoList();
if (loading) return <div>Loading...</div>;
if (error) return <div>Error</div>;
return <div>{JSON.stringify(todoItems)}</div>;
};
export default TodoList;
그리고, 컴포넌트 상에서는 다음과 같이 사용하면 됩니다!