Skip to main content

Command Palette

Search for a command to run...

React 프로젝트에서 삼항 연산자 줄여보기

React 프로젝트에서 가독성을 향상시키기 위해 삼항 연산자를 줄이는 방법을 찾아봤습니다.

Updated
3 min read
React 프로젝트에서 삼항 연산자 줄여보기

삼항 연산자

리액트 프로젝트에서 조건부 렌더링할 때 삼항 연산자를 사용할 수 있다.

  • fetchApi는 특정 데이터를 요청하는 임의의 함수이다.

  • <Person />은 특정 데이터를 렌더링하는 컴포넌트이다.

function App() {
  const queryKey = {
    key: "fetchPeople",
  };
  const {
    data: people,
    isLoading,
    error,
  } = useSWR(queryKey, () => {
    return fetchApi();
  });

  return (
    <div>
      <h1>People</h1>
      {!people ? (
        <p>Empty data</p>
      ) : (
        people.map((person) => {
          return <Person key={person.id} person={person} />;
        })
      )}
    </div>
  );
}

삼항 연산자를 JSX 문법 내부에 사용하기 위해선 중괄호, 물음표, 콜론 등을 작성해야 한다. 삼항 연산자가 여러 개 중첩되면 컴포넌트의 가독성이 떨어진다는 이슈가 있었다. 따라서 삼항 연산자를 대체할 수 있는 별도의 컴포넌트를 작성해 보기로 했다.

두 가지의 필요조건이 있었다.

  • 데이터는 객체 형태로 전달되고, 객체 내 모든 요소가 유효한 값일 때만 보이게 하고 싶다. 즉 객체에 null 또는 undefined 프로퍼티가 없어야 한다.

  • 데이터가 없어도 특정 인자가 true일 때 컴포넌트가 보여야 한다.

  • Stricted 타입은 객체의 모든 요소가 null 또는 undefined가 아님을 나타내기 위해 작성한 유틸리티 타입이다.

Guard 컴포넌트

Props에 children 항목을 함수 형태로 넘겨줄 수 있었고 컴포넌트에 children 항목을 넘겨줄 때는 속성을 직접적으로 명시하지 않고 children 위치에 컴포넌트를 어떻게 렌더링할지를 함수로 작성해주면 된다.

interface LayoutProps {
  children: () => ReactNode;
}
const Layout = (props: LayoutProps) => {
  return props.children();
};
const Section = () => {
  return (
    <Layout>
      {() => {
        return <p>Section</p>;
      }}
    </Layout>
  );
};

GuardProps 타입은 객체 형태의 데이터가 주어질 때 그리고 주어지지 않을 때 두 가지로 나뉘어진다.

isOk로 내부 컴포넌트를 렌더링할지 판단할 수 있고, 결정되는 과정은 다음과 같을 것이다.

  • data가 주어지면 data에 undefined 또는 null 값의 속성이 있는지 검사하고 하나라도 있으면 isOk 변수는 false를 나타낼 것이다.

  • data가 없으면 when 인자로 판단한다.

isOK가 참일 때는 Props로 전달된 내부 컴포넌트가 렌더링된다. 거짓일 때는 따로 fallback으로 지정한 컴포넌트가 없으면 아무것도 렌더링되지 않는다.

import { ReactNode, useMemo } from "react";

type Stricted<T extends Record<string, unknown>> = {
  [key in keyof T]-?: NonNullable<T[key]>;
};

export type GuardProps<T extends Record<string, unknown>> =
  | {
      data?: undefined;
      when: boolean;
      children: () => ReactNode;
      fallback?: ReactNode;
    }
  | {
      data: T;
      when?: true;
      children: (data: Stricted<T>) => ReactNode;
      fallback?: ReactNode;
    };

export const Guard = <T extends Record<string, unknown>>(
  props: GuardProps<T>
) => {
  const { fallback, children } = props;

  const isOk = useMemo(() => {
    if (props.data === undefined) {
      return props.when;
    } else {
      const values = Object.values(props.data);
      return values.every((value) => value !== undefined && value !== null);
    }
  }, [props.data, props.when]);

  const component = useMemo(() => {
    if (!isOk && !fallback) {
      return <></>;
    }
    if (!isOk && !!fallback) {
      return <>{fallback}</>;
    }
    if (!props.data) {
      return (children as () => ReactNode)();
    } else {
      return children(props.data as Stricted<T>);
    }
  }, [children, isOk, fallback, props.data]);

  return component;
};

사용 예시는 다음과 같았다.

사용자가 입력한 title이 10자 이상일 때와 아닐 때를 구분할 수 있다.

import { ChangeEvent, useEffect, useState } from "react";
import { Guard } from "~/components/Guard";

export default function Home() {
  const [title, setTitle] = useState("");
  const onChange = function (event: ChangeEvent<HTMLInputElement>) {
    setTitle(event.target.value);
  };

  return (
    <section>
      <Guard
        data={{ title: title.length < 10 ? null : title }}
        fallback={<span>10자 이상 입력</span>}
      >
        {({ title }) => {
          return <p>Input: {title}</p>;
        }}
      </Guard>
      <input type="text" value={title} onChange={onChange} />
    </section>
  );
}

More from this blog

AI 에이전트에서 작업 맥락을 관리하기 위해 사용한 방법

AI 에이전트의 불편함 Codex CLI와 같은 AI 코딩 에이전트를 통해서 프로젝트 개발 속도를 높일 수 있다. 그리고 혼자 작업했을 때는 놓칠 수 있는 부분도 발생할 수 있는데 AI 에이전트를 통해 보완할 수 있었다. 컴포넌트에 대해서 접근성 태그 작성 API 호출하는 비동기 코드 작성할 때 에러 처리 그리고 AI 에이전트를 잘 활용하면 불가능하

Mar 8, 202610 min read

지시사항을 분할하여 Codex로 효율적인 작업하기

이슈 Codex와 같은 AI 기반 코드 에이전트는 출력 토큰의 수가 제한되어 있다. 그래서 다양한 작업을 하나의 프롬프트에 전부 몰아서 작성하면 원하는 결과가 나오지 않을 수 있다. Codex와 같은 LLM 기반 서비스는 출력 토큰 수를 초과하게 되면 일부 단계가 누락되거나 특정 요소를 과하게 요약할 수 있고 이는 전체적인 답변 퀄리티를 낮출 수 있기 때문이다. 그래서 다양한 AI 공식문서는 특정 작업을 더 작은 단위로 분할하는 방식을 강조한다...

Nov 3, 20255 min read

Key를 활용하여 컴포넌트 상태를 초기화하기

개요 컴포넌트의 상태가 업데이트되어도 컴포넌트 내부에 배치된 컴포넌트의 상태는 그대로 유지되는 경우가 있었다. 예전에는 Props 전달 및 내부에서 useEffect를 통해서 상태를 초기 상태로 업데이트하도록 했는데 useEffect를 남용하게 되면 상태 변화 추적이 어려워지는 문제가 있었다. 그런데 useEffect 외에도 Key를 통해서 컴포넌트 상태를 초기화할 수 있다는 사실을 알게 되었다. 리스트 렌더링 React 프론트엔드에서 목록 형...

Sep 21, 20253 min read

내가 AGENTS.md를 작성하는 방법

Codex CLI 요즘 프로젝트 개발에 Codex CLI를 활용하는 이유는 다음과 같다. 특정 프로젝트를 작업할 때 Claude Code는 종종 사용량을 초과한 것과 다르게 Codex CLI는 ChatGPT Plus 요금제만으로도 토큰 사용량 초과 걱정 없이 충분하게 활용할 수 있었다. 타 CLI 기반 AI 개발 도구에 비해서 요구사항을 더 정확하게 구현하고 꼭 필요한 작업만 진행하기 때문에 코드를 검토하는 시간을 줄일 수 있다. 반복적인 코드...

Sep 21, 20254 min read
N

Nowon Lee

22 posts

React 프로젝트에서 삼항 연산자 줄여보기