조건부 렌더링 & 스타일링

김동현·2022년 3월 23일
2

React

목록 보기
7/27
post-thumbnail
post-custom-banner

조건부 렌더링

조건부 렌더링이란 다른 조건 하에 다른 출력값을 렌더링하는 것입니다.

리액트에서는 조건부 렌더링을 하는 방법이 세 가지가 존재합니다.

  1. 엘리먼트 변수를 사용하는 방식

  2. 삼항 연산자를 사용하는 방식

  3. && 연산자를 사용하는 방식

JSX 문법의 Content 내용에 "빈 문자열, true, false, null, undefined 들은 화면에 렌더링되지 않습니다".

1. 엘리먼트 변수를 사용하는 방식

const MyComponent = {
    const [enteredInput, setEnteredInput] = useState('');
    const changeInputHandler = event => {
        setEnterdInput(event.target.value);
    }
    
    // 리액트 엘리먼트를 할당받을 변수 선언
    let resetButton = null;
    
    // 조건에 따라 할당되는 리액트 엘리먼트가 결정
    if (enteredInput.length > 0) {
        resetButton = <button type='reset'></button>;
    }
    
    return (
        <form>
            <input value={enteredInput} onChange={changeInputHandler} />
            {resetButton}
        </form>
    );
}

위 코드에서 resetButton 이라는 변수가 조건에 따라 할당되는 값이 달라지며 이에 따라 렌더링되는 출력값도 달라집니다.

만약 enteredInput 값의 길이가 0보다 작은 경우 if 조건문이 실행되지 않아 처음에 초기화 된 값인 null로 유지가 되어 아무것도 렌더링되지 않으며, 0보다 큰 경우 if 조건문이 실행되어 resetButton 변수에 버튼 요소가 할당되어 화면에 렌더링될 것입니다.

2. 삼항 연산자를 사용하는 방법

const MyComponent = {
    const [enteredInput, setEnteredInput] = useState('');
    const changeInputHandler = event => {
        setEnterdInput(event.target.value);
    }
    
    return (
        <form>
            <input value={enteredInput} onChange={changeInputHandler} />
            {enteredInput.length > 0 ? (
                <button type='reset'></button>
            ) : null}
        </form>
    );
}

이번에는 삼항 연산자를 사용하는 방법입니다. JSX 문법에서는 값으로 평가되는 자바스크립트 표현식을 {,,,} 안에 넣어 포함할 수 있습니다. 삼항 연산자는 값으로 평가되는 표현식이므로 JSX 문법에 삽입할 수 있으며 삼항 연산자의 조건식에 따라 평가되는 값이 달라집니다.

3. && 연산자를 사용하는 방법

const MyComponent = {
    const [enteredInput, setEnteredInput] = useState('');
    const changeInputHandler = event => {
        setEnterdInput(event.target.value);
    }
    
    return (
        <form>
            <input value={enteredInput} onChange={changeInputHandler} />
            {enteredInput.length > 0 && <button type='reset'></button>}
        </form>
    );
}

&& 연산자를 사용하는 방법도 존재합니다. && 연산자는 좌항이 평가된 값이 truthy 인경우 우항의 값으로 평가되고, 좌항이 평가된 값이 falsy인 경우 그 값으로 평가되어 렌더링되지 않습니다.

"falsy 값중 0을 제외한 나머지 값들은 화면에 렌더링되지 않습니다".

조건 명령문 반환

조건부 렌더링과 유사한 방법으로 어떠한 조건일 만족할 때 컴포넌트가 반환하는 JSX 부분 "전체가 변경"된다면 조건문을 사용하여 다른 JSX 코드를 반환(return)하도록 작성할 수 있습니다.

const MyComponent => {
    const [lists, setLists] = useState([]);
    
    if (lists.length === 0) {
        // lists 길이가 0이라면 렌더링될 리액트 엘리먼트
        return (
            <h2>No Comtents.</h2>
        );
    }

    return (
        // lists의 길이가 0이 아닌 경우 렌더링될 리액트 엘리먼트
        <ul>
            {lists.map(list => {
                return (
                    <li key={list.id}>{list.content}</li>
                );
            }
        </ul>
    );
}

위 코드에서 lists라는 배열을 상태로서 갖고 있는 컴포넌트입니다. 이때 lists 배열의 길이가 0이라면 <h2>No Contents</h2>를 반환하고, 0이 아니라면 lists 배열의 요소를 모두 순회하면서 <ul>,,,<ul>을 반환하도록 합니다.

즉, 어떠한 조건에 따라 반환되어야하는 "JSX 코드 전체가 바뀌는 경우"에는 위에서 처럼 if 조건문 안에서 return 문을 사용하여 JSX 코드가 반환되도록 작성해줍니다.
만약 JSX 코드 전체가 바뀌지 않고 어느 "특정 부분"만이 바뀐다면 앞에서 살펴본 세 가지 조건부 렌더링을 사용하는 것이 더 효율적입니다.

조건부 스타일링

어떠한 조건에 따라서 스타일이 변경되어야 할 때 동적으로 인라인 스타일 설정하는 방법과 동적으로 CSS 클래스를 설정하는 방법이 있습니다.

동적 인라인 스타일 설정

참고로 JSX 코드를 사용한 기본 내장 HTML 엘리먼트는 style을 사용하여 인라인 스타일링을 할 수 있습니다. style은 객체를 값으로 가지며 객체의 프로퍼티로 CSS 프로퍼티를 작성합니다.

주의할 점으로 CSS 프로퍼티는 케밥 케이스를 사용하지만 JSX에서 style prop의 프로퍼티로 작성할 때는 카멜 케이스를 사용하거나 CSS 프로퍼티 이름을 그대로 사용하고 싶다면 따옴표를 포함하는 문자열 또는 대괄호 표기법으로 계산된 프로퍼티를 사용하여 작성합니다.

<div style={{ width: '100px', heigth: '100px', 'background-color': 'red', borderColor: 'green'}}></div>;

기본 내장 HTML 엘러먼트를 JSX 코드로 작성하는 경우 style에 객체를 작성하여 엘리먼트의 인라인 스타일을 설정할 수 있습니다.


// MyComponent.js

const MyComponent => {
    ,,,
    return (
        <form onSumbit={formSubmitHandler}>
            <label style={{ color: !isValid ? 'red' : 'black' }}>Todos</label>
            <input style={{ borderColor: !isValid ? 'red' : '#ccc', backgroundColor: !isValid ? 'salmon' : 'transparent' }} type="text" value="enteredInput" onChang={changeInputHandler} />
            <button type="sumbit"></button>
        </form>
    );
}

return 문에 작성된 JSX 코드에서 label 엘리먼트는 isValid의 상태에 따라 css 프로퍼티인 color 값이 결정됩니다. 만약 isValid의 값이 true라면 black으로, false라면 red로 적용됩니다. 그리고 input 엘리먼트에서도 isValid의 상태에 따라서 border-color, background-color 프로퍼티 값이 동적으로 결정됩니다.

동적 CSS 클래스 설정

// MyComponent.js


const MyComponent => {
    ,,,

    return (
        // className 값으로 템플릿 리터럴을 사용하여 동적 스타일링
        <form className={`form-control ${!isValid ? 'invalid' : '' }`} onSumbit={formSubmitHandler}>
            <label>Todos</label>
            <input type="text" value="enteredInput" onChang={changeInputHandler} />
            <button type="sumbit"></button>
        </form>
    );
}

위 코드에서는 form 엘리먼트에 className prop 값을 결정할 때 "템플릿 리터럴"을 사용하여 자바스크립트 표현식이 동적으로 삽입되도록 작성하였습니다. isValid 상태가 true라면 'form-control'으로 결정되고, false라면 'form-control inValid'로 결정됩니다.

profile
Frontend Dev
post-custom-banner

0개의 댓글