본문 바로가기
학원에서 배운 것/React

KDT 5th 웹개발자 입문 수업 39일차

by 쿠리의일상 2023. 3. 30.

조건부 렌더링

컴포넌트를 상황에 따라 켜고 끄려면 -> 조건부 렌더링이 필요

원래 js, html 에서는 display 속성을 none 으로 처리해줬지만 리액트는 jsx 문법을 사용하므로 if 문/3항 연산자/논리 연산자와 html 태그를 같이 사용해주면 되므로 display 속성을 처리할 필요가 없다.

 

export default function CoditionalState() {
  const [isVisible, setIsVisible] = useState(false);
  const toggle = () => {
    setIsVisible(!isVisible);
  };

  return (
    <div>
      <button onClick={toggle}>{isVisible ? 'Off' : 'On'}</button>
      {isVisible && <ConditionalRender />}
    </div>
  );
}

&& 연산자를 사용하면 display 속성을 사용할 필요 없이, 단락 회로 평가를 이용하여 보이게/안보이게 가능하다.

 

 

단락 회로 평가 (short circuit evaluation)

왼쪽에서 오른쪽으로 연산하게 되는 논리 연산자의 연산 순서를 이용하는 문법

truthy, falsy 

truthy falsy
그외의 값 모두
빈 배열 [ ], 빈 객체 { } 등 모두! 
undefined
null
NaN
0
'' (빈문자열)

 

 const getName = (person) => {
  return person && person.name;
};

이 경우, Person 값에 undefined 가 들어간다면 person.name 에 접근하지 못하고 바로 person인, undefined 를 리턴하게 된다.

추가로 해당 경우에서 변수로 값을 받아주고 || 로 처리를 해주면

const getName = (person) => {
  const name = person && person.name;
  return name || "객체가 아닙니다";
};

person에 undefined 가 들어가서 name 에는 undefined 가 들어가고 undefined 를 || 연산을 해주면 falsy 이므로 객체가 아닙니다 가 리턴되는 형태이다.

|| 의 경우 앞의 조건이 truthy 하면 값을 반환하는 것으로 뒤에 조건을 확인하지 않고 종료해버린다.

 

console.log(true && 'hello'); // hello
console.log(false && 'hello'); // false
console.log('hello' && 'bye'); // bye
console.log(null && 'hello'); // null
console.log(undefined && 'hello'); // undefined
console.log('' && 'hello'); // ''
console.log(0 && 'hello'); // 0
console.log(1 && 'hello'); // hello
console.log(1 && 1); // 1

위의 예제를 보다시피, A && B 연산자를 사용하게 될 때, A 가 truthy 한 값이라면 B 가 리턴되고,

A 가 falsy 한 값이 되면, A 가 리턴되는 속성이 있다.

 

반대로 A || B 를 사용하면 A 가 truthy 하면 A 가 리턴

A 가 falsy 하다면 B 가 리턴된다.

 

 

Lifecycle 생명 주기

Mount : 컴포넌트가 최초에 화면에 등장할 때 -> componentDidMount

Update : 컴포넌트의 state / props 가 변화할 때 -> componentDidUpdate

Unmount : 화면에서 사라질 때 -> componentWillUnmount

클래스 컴포넌트의 Lifecycle

컴포넌트별 상태 관리 및 리렌더링이 있기에 리액트는 Lifecycle에 대한 기능이 다수 있다.

 

함수 컴포넌트의 Lifecycle

-> useEffect 훅을 사용해준다.

useEffect(콜백함수, deps배열)

두번째 인자로 dependency Array 를 받아주는데 해당 배열에는 변수를 넣을 수 있으며,

해당 변수가 변경될 때에만 useEffect 내부의 함수가 실행된다.

 

// Mount 를 포함하여 렌더링 될 때마다(변경이 일어날 때마다) 실행
useEffect(() => { });

그냥 컴포넌트에 리렌더링 될 때마다 실행하는 것과 차이점은,

컴포넌트의 리렌더링 되는 것은 순차적으로 코드 실행이 되지만

useEffect(() => {}) 을 사용해주면, return () 부분이 다 그려지고 나서 실행되므로 비동기적인 코드 실행이 가능 ? 한 것이다. (defer 속성과 유사하다고 함)

 

// Mount 될 때만 실행
useEffect(() => { }, []);

빈 배열을 둬서 변화를 감지할 필요가 없으므로 최초 마운트 시에만 실행됨

 

// 첫 렌더링 될 때(Mount) + value 가 변할 때만 실행
useEffect(() => { }, [ value ]);

 

// Unmount 될 때 return 안의 함수가 실행됨
useEffect(() => { 
	// 구독
    return () => {
    	// 구독 해지
    }
}, []);

useEffect 정리하기 - Unmount

클래스형에서는 componentWillUnmount 메서드를 사용했지만 함수형에선 useEffect 의 return 에 함수를 주면 된다.

 

cleanup 을 사용한 타이머 예제

import React, { useState } from 'react';
import PracticeTimerItem from './PracticeTimerItem';

export default function PracticeTimer() {
  const [isVisible, setIsVisible] = useState(true);
  const toggle = () => {
    setIsVisible(!isVisible);
  };

  return (
    <div>
      {isVisible ? (
        <button onClick={toggle}>보이기</button>
      ) : (
        <>
          <PracticeTimerItem toggle={toggle} />
        </>
      )}
    </div>
  );
}
export default function PracticeTimerItem({ toggle }) {
  const pickTime = useRef(0);
  const [timer, setTimer] = useState(0);

  useEffect(() => {
    const time = setInterval(() => {
      pickTime.current++;
      console.log(pickTime.current, '초, 타이머 작동 중');
    }, 1000);

    return () => {
      clearInterval(time);
    };
  }, []);

  const onPickTime = () => {
    setTimer(pickTime.current);
  };

  return (
    <div>
      <h1>{timer}</h1>
      <button onClick={onPickTime}>현재 타이머</button>
      <button onClick={toggle}>타이머 숨기기</button>
    </div>
  );
}

 

useEffect의 실전 활용

컴포넌트가 서버로부터 데이터를 받아와야 하는 상황에서 많이 사용된다.

 

컴포넌트가 최초 마운트 -> 서버로부터 데이터를 요청 -> 데이터를 State 에 등록 -> 해당 내용을 렌더링

이러한 흐름을 많이 사용한다.

 

리액트는 이미 npm 이 관리하는 폴더이므로 패키지 모듈만 설치하여 사용해주면 간단한 백엔드 서버를 구성해줄 수 있다.

 

npm i -S express cors 설치

 

백엔드 데이터를 받아서 그려줄 컴포넌트를 생성해주고

함수가 Mount 되면 fetch() 함수를 이용하여 만들어 준 api 로 데이터를 요청하고 해당 데이터를 받아서 state 에 부여한다!