?
) → 논리곱 연산자(&&
)삼항 연산자를 중첩해서 사용하는 것보다 논리곱 연산자를 사용하면 더 가독성 좋은 코드를 작성할 수 있다.
아래 코드는 삼항 연산자를 3중으로 중첩해서 사용하고 있다.
function Greeting({ isEvent, isLogin, name, cash }) {
return (
<div>
저희 사이트에 방문해 주셔서 감사합니다.
{isEvent ? ( // isEvent가 true일 때 보이는 부분
<div>
<p>오늘의 이벤트를 놓치지 마세요.</p>
<button onClick={onClickEvent}>이벤트 참여하기</button>
</div>
) : isLogin ? ( // isEvent는 false일 때 보이는 부분
cash <= 100000 ? ( // isLogin이 true일 때 보이는 부분
<div> // cash가 100000 이하일 때 보이는 부분
<p>{name}님 안녕하세요.</p>
<p>현재 보유하신 금액은 {cash}원입니다.</p>
</div>
) : null // cash가 100000 이상일 때 null
) : null} // isLogin이 false일 때 null
</div>
);
}
&&
)이를 && 연산자로 조건부 렌더링 하면 아래처럼 작성할 수 있다.
function Greeting({ isEvent, isLogin, name, cash }) {
return (
<div>
저희 사이트에 방문해 주셔서 감사합니다.
{isEvent ? ( // isEvent가 true일 때 보이는 부분
<div>
<p>오늘의 이벤트를 놓치지 마세요.</p>
<button onClick={onClickEvent}>이벤트 참여하기</button>
</div>
)}
{!isEvent && isLogin && cash <= 100000 && ( // isEvent는 false이고, isLogin과 cash가 10000 이상일 때 보이는 부분
cash <= 100000 ? (
<div>
<p>{name}님 안녕하세요.</p>
<p>현재 보유하신 금액은 {cash}원입니다.</p>
</div>
)}
</div>
);
}
&&
)&&
연산자는 왼쪽에서 오른쪽으로 값을 평가하다가 처음으로 만나는 거짓값을 반환하거나,
const v1 = 'ab' && 0 && 2; // v1 = 0
모두 참이라면 마지막 값을 반환한다.
const v2 = 'ab' && 1 && 2; // v2 = 2
||
)||
연산자는 왼쪽에서 오른쪽으로 값을 평가하다가 처음으로 만나는 참값을 반환하거나,
const v3 = 'ab' || 0; // v3 = 'ab'
const v4 = '' || 0 || 3 || false; // v4 = 3
모두 거짓이라면 마지막 값을 반환한다.
const v5 = '' || 0 || undefined || false; // v5 = false;
아래의 코드에서 cash
가 0일 경우
&&
연산자는 처음으로 만난 falsy 값을 평가하기 때문에, 0을 반환한다. (의도대로라면 '0원 보유중'이 렌더링되어야 함)
이럴 경우 앞에 not을 두 번(!!
)을 붙여 0을 명확하게 boolean 타입으로 변환시켜줘야 한다.
<div>
{cash && <p>{cash}원 보유 중</p>} // 0
{!!cash && <p>{cash}원 보유 중</p>} // 0원 보유중 (!!cash가 false가 되었으므로)
</div>
아래의 경우에서도 memo
가 빈 문자열일 경우
'200자 입력 가능'이 아닌 빈 문자열이 반환되므로 아래처럼 수정해줄 수 있다.
<div>
{memo && <p>{200 - memo.length}자 입력 가능</p>} // ''
{!!memo && <p>{200 - memo.length}자 입력 가능</p>} // 200자 입력 가능
</div>
또는 아예 cash
나 memo
가 null
이나 undefined
가 아니라고 명확하게 표현해주는 것도 좋다.
<div>
{cash !== null && <p>{cash}원 보유 중</p>} // 0원 보유중
{memo !== null && <p>{200 - memo.length}자 입력 가능</p>} // 200자 입력 가능
</div>
논리곱 연산자를 사용할 때도 조건이 많아지면 삼항 연산자와 마찬가지로 체인이 길어지면서 가독성이 떨어지게 될 수 있다. 아래의 코드를 보자.
function ListPage() {
const { data, isLoading, error } = useGetData();
return (
<Layout>
{isLoading && <LoadingSpinner />} // 로딩중이면 로딩 스피너 표시
{!isLoading && !!error && <ErrorMessage message={error.message} />} // 로딩이 끝났는데 에러가 있다면 에러 메세지 표시
{!isLoading && !error && !!data && data.items.map((item) => ( // 로딩이 끝났고 에러도 없다면 데이터 표시
<Item key={item.id} item={item} />
))}
</Layout>
);
}
이런 경우 조건문 체인을 추출해서 변수로 만들 수 있다.
변수 showError
는 로딩이 끝나고, 에러가 있는 경우 true
값을 가지고,
변수 showData
는 로딩이 끝나고, 에러가 없고, 데이터가 있을 때 true
값을 가진다.
이렇게 하면 JSX문을 훨씬 읽기 쉽게 작성할 수 있다.
function ListPage() {
const { data, isLoading, error } = useGetData();
const showError = !isLoading && !!error;
const showData = !isLoading && !error && !!data;
return (
<Layout>
{isLoading && <LoadingSpinner />}
{showError && <ErrorMessage message={error.message} />}
{showData && data.items.map((item) => (
<Item key={item.id} item={item} />
))}
</Layout>
);
}
students
는 배열이며 undefined
가 될 수 있는 값이여서 아래처럼 값이 undefined
인지 검사하고 있다.
<div>{students && students.map(/* ... */)}</div>
이런 경우 배열의 기본값을 undefined
가 아니라 빈 배열([]
)로 주면 코드를 더 간결하게 작성할 수 있다.
<div>{students.map(/* ... */)}</div> // 빈 배열인 경우 아무것도 렌더링되지 않음
조건부연산자를 쓰면 더 가독성도 좋고 코드도 짧아질거 알면서 손으로는 삼항연산자를 쓰고있었는데.. 다시금 복습하고 갑니당 !!