조건부 렌더링
컴포넌트를 상황에 따라 켜고 끄려면 -> 조건부 렌더링이 필요
원래 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 에 부여한다!
'학원에서 배운 것 > React' 카테고리의 다른 글
KDT 5th 웹개발자 입문 수업 41일차 (0) | 2023.04.03 |
---|---|
KDT 5th 웹개발자 입문 수업 40일차 (0) | 2023.03.31 |
KDT 5th 웹개발자 입문 수업 38일차 (0) | 2023.03.29 |
KDT 5th 웹개발자 입문 수업 37일차 (0) | 2023.03.28 |
KDT 5th 웹개발자 입문 수업 36일차 (0) | 2023.03.27 |