[React] 2강 생명주기

youngseo·2022년 7월 27일
0

REACT

목록 보기
33/52
post-thumbnail

자료

React 의 생명주기

React에서는 컴포넌트가 표시되고 사라지는 순간까지를 하나의 생명 주기로 표현했습니다.

  • useEffect는 렌더가 된 이후에 진행되는 과정으로 크게 아래와 같이 나뉩니다.
  • mount(컴포넌트가 표시될때) => update(컴포넌트 내부요소 업데이트될 때) => unmount(컴포넌트가 사라질 때)

1. mount (컴포넌트가 표시될 때)

  • api호출의 경우 대체로 useEffect안 실행할 함수 부분에 작성을 합니다.
  • 두번째 인자인 배열은 빈배열을 사용합니다.
useEffect(컴포넌트가 표시될 때 실행할 함수, []);

2. update (컴포넌트 내부 요소가 업데이트될 때)

  • ex)드롭다운 메뉴를 만들 때
  • 두번 째 인수인 배열 안에 관찰한 state를 넣어줍니다.
useEffect(오른쪽 리스트에 적은 요소들이 업데이트되는 시점에 실행할 함수, [업데이트 되는지 지켜볼 변수/State]);

3. unmount (컴포넌트가 사라질 때)

  • 메모리누수를 방지하기 위해 사용을 합니다.
  • return 과 함께 작성을 합니다.
useEffect(() => {return () => 컴포넌트가 사라질 때 실행할 함수})

🎲Loading화면 만들기 예제

$ yarn create react-app second-app

1. mount

API호출 대신 setTimeout을 이용해 연습 코드를 작성해보도록 하겠습니다.

import React, {useEffect, useState} from 'react'

function Loading() {
  const [isLoaded, setIsLoaded] = useState(false) //1.

  useEffect(()=>{ //3. 
    //컴포넌트가 렌더링될 때 실행될 함수
    //데이터 갖고오기 요청보내고, 데이터가 오면 isLoaded = true
    setTimeout(() => {
      setIsLoaded(true) //4.
    },3000)
  }, [])

  return (
    <div>
      {isLoaded ? <>로딩완료!</> : <>로딩 중</>} //2.
    </div>
  )
}

export default Loading
  1. isLoaded로 state를 하나 만들어줍니다.
  2. isLoaded가 true이면 화면에 로딩완료!가 false이면 로딩 중이 뜨도록 설정해줍니다.
  3. useEffect을 사용해 컴포넌트가 렌더될 때 실행될 함수를 하나 정의해줍니다.
  • 컴포넌트가 렌더링될 때 실행될 함수
  • 데이터 갖고오기 요청보내고, 데이터가 오면 isLoaded = true
  • 연습은 API호출 대신 setTimeout을 사용해보도록 하겠습니다.
  • 3초가 지난 후 Loaded값을 true로 바꿔줍니다.

2. update

import React, {useEffect, useState} from 'react'

function Loading() {
  const [isLoaded, setIsLoaded] = useState(false)
  const [text, setText] = useState([])  //2. 새로운 상태값 생성

  useEffect(()=>{
    setTimeout(() => {
      setIsLoaded(true)
    },3000)
  }, [])

  useEffect(() => { // 1. 로딩이 완료로 변화되면 ~가 실행되도록
    setText(text.concat(['추가!'])) //3. 업데이트 될 때 실행될 함수
  }, [isLoaded])

  return (
    <div>
      {isLoaded ? <>로딩완료!</> : <>로딩 중</>}
      {text} //4.
    </div>
  )
}

export default Loading
  1. 로딩이 완료되면 변화되는 ~함수가 실행될 수 있도록 하나 더 만들어줍니다.
  • 관찰할 대상인 isLoadeduseEffect의 두번째 인자의 배열에 넣어줍니다.
  1. 새로운 state를 하나 생성해줍니다.
  2. 로딩이 완료되면 실행될 함수를 하나 정의해줍니다.
  3. {text}

그런데 추가가 하나가 아닌 두개가 들어간 것을 확인할 수 있습니다.

  • 업데이트 될 때 실행되게 만들더라도 처음 컴포넌트가 렌더링될 때 실행이 되기 때문에 2번 실행이 된 것입니다.
  • 업데이트 될 때만 실행시키고 싶다면 if문을 추가하면 됩니다.
    • if(isLoaded) setText(text.concat(['추가!']))

현재 isLoaded에 노란 warning메세지가 뜨는 것을 확인할 수 있습니다.

  • 이는 text라는 상태도 지켜보라는 의미입니다.
    • 즉 useEffect안에서 사용하고 있는 state값도 배열에 넣으라는 것입니다.
    • 단, 의도치 않게 재귀호출을 할 수 있기 때문에 변하지 않을 값이라면 warning이 떠도 괜찮습니다.

🎲 버튼 렌더링 예제

  1. 처음 화면에 들어가면 아무것도 보이지 않고, 5초 후에 요소들이 표시됩니다.
  2. 처음에는 현재 지역 / 세부 지역에 아무것도 표시되지 않지만, 서울 혹은 부산을 클릭하는 순간, 현재 지역이 클릭한 지역으로 바뀌고, 클릭한 지역에 맞춰서 세부 지역도 바뀝니다.
import React, {useState, useState} from 'react'

function ButtonRender(){
  const [isLoaded, setIsLoaded] = useState(false)
  const [loc, setLoc] = useState()
  const [subLoc, setSubLoc] = useState([])
  
  useEffect(() => {
    setTimeout(()=>{
      setIsLoaded(true)
    }, 2000)
  }, [])
  
  useEffect(() => {
  	if(loc==='서울') setSubLoc(['명동', '강남'])
    if(loc==='부산') setSubLoc(['해운대'])
  }, [loc])
  
  return (
    <>
    {isLoaded && <>
      <button onClick={() => {setLoc('서울')}}>서울</button>
      <button onClick={() => {setLoc('부산')}}>부산</button>
      <p>현재지역: {loc}</p>
      <p>세부지역: {subLoc}</p>
     </>}
    </>
  )
}
export default ButtonRender

🎲 타이머 예제

  1. props를 이용해 초기 시간을 값을 받습니다
  2. 시작 버튼을 클릭하면 1초마다 시간이 감소됩니다.
  3. 중지 버튼을 클릭하면 더이상 시간이 카운트 다운되지 않습니다.
import React, {useEffect, useState} from 'react'

function Timer({s}) { //s로 props를 받아옵니다.
  const [seconds, setSeconds] = useState(s) //받아온 s를 초기값으로 설정
  const [isClicked, setIsClicked] = useState(false)

  useEffect(() => {
    //isClicked가 true일 때 seconds 관찰하며 1초마다 seconds-1
	if(isClicked) {
      const countDown = setTimout(()=>{
      	setSecondes(seconds-1)
      }, 1000)
    }
    //isClicked가 false인 경우 unmount
    return () => {clearTimeout(countDown)}
  }, [seconds, isClicked])

  return (
    <>
    <div>{seconds}</div>
    <button onClick={()=>{setIsClikced(true)}}>시작</button>
    <button onClick={()=>{setIsClikced(false)}}>중지</button>
    </>
  )
}

export default Timer

🎲 시계

moment플러그인을 이용해 1초씩 시간이 흘러가는 시계를 만들어보세요.

$ yarn add moment moment-timezone
import React, { useState, useEffect } from 'react'
import moment from 'moment'

function TimeZone() {
  const [time, setTime] = useState(moment().format('YYYY-MM-DD HH:mm:ss'))

  useEffect(() => {
    setTimeout(() => {
      setTime(moment().format('YYYY-MM-DD HH:mm:ss'))
    }, 1000)
  }, [time])

  return <div>{time}</div>
}

export default TimeZone

0개의 댓글