함수형 리액트 프로그래밍

Park June Chul·2022년 1월 18일
0

DRAFT

프로그램을 함수형으로 만들기

가상의 게시판을 만든다고 가정해 보겠습니다.

const ArticleBoardPage = () => {
  const [user, setUser] = useState();
  const [articles, setArticles] = useState();
  const page = window.location.query.page;
  
  useEffect(() => {
    setUser(await fetchUser());
    setArticles(await fetchArticles(page));
  }, []);
  
  return (
    <div>
      <div>
        {user.name}님 안녕하세요<br/>
        작성 글: {user.articles.length}</div>
      <div>
        {articles.map(article => (
          <div>
            {article.title} - {article.author}
          </div>
        )}

        <button onClick={() => window.location.href='/write'}>
          글쓰기
        </button>
      </div>
    </div>
  );
}

위 코드는 간단하게 작성할 수 있는 못 짠 게시판 코드이며, 전혀 함수형스럽지 않습니다.

왜 함수형스럽지 않을까요?

  • 상태를 가집니다.
  • 인풋과 아웃풋이 뒤죽박죽입니다.

만약 위 코드가 아래와 같이 되면 어떨까요?

const ArticleBoardPage = () => { 
  return (
    <div>
      <UserProfile />
      <ArticleList
        page={window.location.query.page}
      />
    </div>
  );
};

단순히 코드를 묶어서 컴포넌트화 했다고 생각하시나요?

각 컴포넌트를 한번씩 살펴보도록 하겠습니다.

<UserProfile userId={myUserId} />
  • 이 컴포넌트는 input(userId)에 대해 항상 같은 output(UserProfile UI)를 반환합니다.
  • 단순히 상태가 외부에서 내부로 들어갔다고 생각하시나요?
    • 네 맞습니다. 이것은 추상화의 일종입니다.
    • 상태가 단단하게 숨어있을 경우 이것은 아무런 문제가 되지 않습니다. (함수형 js 프로그래밍의 대명사(;;)인 map 도 내부적으론 i 라는 상태를 가지겠죠?)
<ArticleList page={1} />
  • 이 컴포넌트는 input(page-no)에 대해 항상 같은 output(ArticleList UI)를 반환합니다.
const BigHugeMonolithApp = () => ProfilePage
  | LoginPage
  | SignUpPage
  | SettingPage
  | ArticlePage;
const TinyArticleComponent = () => Article;

const TinyArticleComponent = () => Article
  | LoadingComponent
  | ErrorRetryComponent;

(아무리 잘 짜도 App은 결국 위 코드처럼 될 수밖에 없습니다. 그냥 monolith식 컴포넌트를 만들수록 '함수형'의 컨셉이 망가진다고 생각해주세요.)

순수 컴포넌트 (순수 함수)

컴포넌트 합성 (함수 합성)

// 이 컴포넌트는 화면의 맨 위에 네모를 출력합니다.
// 일반적인 다이얼로그/모달 컴포넌트입니다.
<Dialog />
// 이 컴포넌트는 유저 정보를 출력합니다.
<UserProfile />
// 이제 화면의 맨 위에 표시되는 모달 안에
// 유저 정보가 출력됩니다.
<Dialog>
  <UserProfile />
</Dialog>

눈치채셨나요?

컴포넌트를 잘게 쪼개서 함수 에 가깝게 만들수록 재사용성(가지고 놀 수 있는 범위)가 늘어납니다.

훅 합성 (함수 합성)

훅 또한 그 자체로 함수이며, 합성의 대상이 될 수 있습니다.

// 게시물 목록을 가져옵니다.
useArticles();
// 내가 숨김처리 설정한 키워드 목록을 가져옵니다.
useBannedKeywords();
// 내가 숨김처리 설정한 키워드가 포함되지 않은
// 게시물 목록을 가져옵니다.
const useRefinedArticles = () => {
  const articles = useArticles();
  const bannedKeywords = useBannedKeywords();
  
  return articles
  	.filter(x => !bannedKeywords.some(y => x.body.includes(y));
};

고차 컴포넌트 (고차 함수)

profile
다른 곳에서 볼 수 없는 이상한 주제를 다룹니다. https://pjc0247.github.io/new-home

0개의 댓글