TIL - React (2)

January·2022년 7월 27일
0

Frontend

목록 보기
14/31
post-custom-banner

react 생명주기

  1. mount (컴포넌트가 표시될 때)
    • 백엔드에서 데이터를 받을 때
    • useEffect(컴포넌트가 표시될 때 실행할 함수, [여기는 빈 대괄호입니다]);
  2. update (컴포넌트 내부의 요소가 업데이트될 때)
    • 데이터가 변화될때
    • useEffect(오른쪽 리스트에 적은 요소들이 업데이트되는 시점에 실행할 함수, [업데이트 되는지 지켜볼 변수/State]);
  3. unmount (컴포넌트가 사라질 때)
    • 메모리 누수 방지
    • useEffect(() => {return () => 컴포넌트가 사라질 때 실행할 함수})

로딩화면 예제

js파일, jsx파일의 차이점은 없다. 단지 명시적으로 jsx로 쓰인 코드면 jsx파일로 만든다. 대부분의 회사에서는 대부분의 컴포넌트는 jsx로 쓴다.

mount

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

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

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

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

update

function Loading() {
  const [isLoaded, setIsLoaded] = useState(false)
  const [text, setText] = useState([])

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

  // 로딩이 완료로 변하면 실행
  useEffect(() => {
    // 업데이트될 때 실행되는 함수 + 처음 컴포넌트가 렌더될때도 실행된다.
    if(isLoaded) setText(text.concat([' 추가!']))
  }, [isLoaded]) // 너가 여기 안에 쓴 그 값이 업데이트되지 않은 상태로 반영이 될수있으니 text를 지켜보도록 작성을 해라 하지만 우리의 목적과는 별개이기도 하고 text변수도 넣어주면 재귀적으로 '추가!' 문자가 추가된다.
  return (
    <div>
      {isLoaded ? <>로딩 완료!</> : <>로딩 중</>}
      {text}
    </div>
  )
}

타이머 예제

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

function Timer({s}) {
  const [seconds, setSeconds] = useState(s)
  const [isClicked, setIsClicked] = useState(false)

  useEffect(() => {
    if(isClicked) {
      const countDown = setTimeout(() => {setSeconds(seconds - 1)}, 1000)
      return () => clearTimeout(countDown) // 컴포넌트가 꺼질때 셋타임아웃도 꺼진다.
    }
  }, [seconds, isClicked]) // 지켜볼 변수

  return (
    <div>
      <div>{seconds}</div>
      <button onClick={() => setIsClicked(true)}>타이머 시작</button>
      <button onClick={() => setIsClicked(false)}>타이머 종료</button>
    </div>
  )
}


export default Timer

세계시간 예제

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

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

  useEffect(() => {
    const seoul = setTimeout(() => setTime(moment().format('YYY-MM-DD HH:mm:ss')), 1000)
    return clearTimeout(seoul)
  }, [time])
  return (
    <>
      <strong>현재 시각</strong>
      <p>{time}</p>
    </>
  )
}

export default Clock

함수형 대신 클래스

CRA로 프로젝트를 만들면 클래스를 이렇게 작성되도록 플러그인이 설치가 되어있다.

import React, { Component } from 'react';

class Comp extends Component {
  // const [num, setNum] = useState(0)과 같다.
  state = {
    num: 0
  }  
  countUp = () => {
    this.setState({
      num: this..state.num + 1. // 위에 작성한 state 안의 num 값을 갖고 오게 됨
    })
  }

  render() { // render() 를 붙여줘야만 렌더가 됨
    const { name } = this.props; // 클래스는 props에 this를 붙여줘야한다.

    return (
      <div>
        <h1>{this.state.num}</h1>
        <button onClick={this.countUp}>카운트 업!</button>
      </div>
    );
  }
}

export default Comp;

이벤트 처리

인자가 없을때는 이벤트가 자동으로 넘어간다.

  • onClick
  • onChange
    • const onUserInputChange = (e) => {
        const { name, value } = e.target
        setUserInput({...userInput, [name]: value}) // id 또는 pw만 할당되는 상황이라서 ...전개 연산을 해줌으로써 id와 pw에 각각 데이터가 들어가고서 다시 합쳐서 들어온다
      }
      <input placeholder='아이디를 입력해주세요' onChange={onUserInputChange} name="id"/>
      <input placeholder='비밀번호를 입력해주세요' onChange={onUserInputChange} type="password" name="pw"/>
  • onBlur
  • onFocus
  • onKeyDown
    • onKeyPress는 죽었다. 권장하지 않으니 키다운으로 사용하자.
      const KeyHandler = (e) => {
       if(e.key === 'Enter') {
         // 엔터 눌렀을때 실행될 것
       }
      }
      <input onKeyDown={KeyHandler} />

로그인시 input값 가져오기
onChange 또는 ref를 활용해서 input값을 가져온다.
하지만 onChange를 더 많이 사용한다.
실시간 예외처리와 상태관리에 더 장점이 있어서이다.

useRef

재렌더링 되지 않는 효율적인 변수 만든다. 값이 변해도 재렌더링이 되지 않는 변수를 만들고자 할 때 사용할 수 있다. 변수 만드는 과정에서 메모리를 최소화하고 싶을때 useRef를 쓰게된다.

tip

어떤 요소를 제거할때 filter 메서드가 가장 옳은 방식이다.

const [times, setTimes] = useState([{id: 1, tz: 'Asia'}, {id: 2, tz: 'America'}])

<button onClick={() => {setTimes(time.filter(timeElement => timeElement.id !== time.id))}}> 제거하기<button>
post-custom-banner

0개의 댓글