16) 넷째주 월요일

이희주·2022년 5월 30일
0
post-thumbnail

React

input 태그로 스테이트 합치기

이 내용들을
얕은복사를 이용해서
이렇게 바꿔준 후
또 얕은복사를 이용해서
이렇게 바꿔줄 수 있음

Class

class란?
: 객체이자, 물건 만드는 설명서

class안에는 함수와 변수를 넣을 수 있고, 이 변수와 함수를 조합해 붕어빵과 몬스터를 만드는 방법을 적어둘 수 있다.

그리고 붕어빵과 몬스터를 만들고 싶다면 new 붕어빵() 으로 만들어 준다.
만들어진 붕어빵과 몬스터는 객체 또는 인스턴스라고 부른다!
(붕어빵,몬스터 만드는 설명서로 붕어빵,몬스터를 찍어냈따)

클래스에서의 함수와 변수 사용법

get date의 경우

이렇게 사용하려면 설명서에
이런 내용의 함수들이 들어가 있어야 한다
근데 자세히보니까
function, const, let 같은게 없다??
=> 클래스에서 함수와 변수를 사용 할 때는 function, let, const를 붙이지 않는다
=> 클래스에서 만들어진 함수를 메소드 라고 부른다 (ex. .getFullYear() , .getMonth() )

date는 객체(=인스턴스) 로 볼 수 있기 때문에
date.getFullyear() 로 점 . 을 붙여서 사용 할 수 있다.
=> 이걸 객체지향프로그래밍-OOP 라고 부른다

class component 만들기 실습

// class component 만들기 실습
import { Component } from "react";
//render, setState등을 상속받아 사용하기 위해 리액트에서 제공해주는 컴포넌트라는 extends 사용하기

export default class ClassCounterPage extends Component {
  //state 만들기 (기존에는 useState() 사용해서 만들었지만, class는 그런거 업슴 그냥 냅다 만들어)
  state = {
    count: 0,
  };

  //카운트 올리는 함수 만들기
  onClickCounter = () => {
    //this는 실행주체에 따라서 다르게 나오기 때문에, 화살표 함수로 써서 변화하는 this를 class로 고정시켜주기
    //화살표 함수를 쓰지 않고 직접 바인딩 할 때는 onClick={this.onClickCounter.bind(this)} 라고 적어줘야 함
    this.setState((prev) => ({
      // state자체가 객체이기 때문에 객체로 나오게 하기
      count: prev.count + 1,
      // prev안의 count에 더하기 1 해주기
    }));
  };

  //화면에 그려주는 함수 만들기
  render() {
    return (
      <div>
        <div>현재카운트: {this.state.count}</div>
        {/* state 값 보여주기 */}
        {/* class는 this 라는 애를 가지고 있는데, 얘를 사용하면 현재 가지고 있는 함수를 사용 할 수 있음 */}
        {/* this.state.count = ClassCounterPage 안에있는 state 안에있는 count */}
        <button onClick={this.onClickCounter}>카운트 올리기</button>
      </div>
    );
  }
}

Ref

class형 컴포넌트 createRef()

class형 컴포넌트에는 createRef() 메서드를 이용해 특정 태그에 접근

//메서드 임폴트
import {createRef} from 'react'

// Ref코드 생성
inputRef = createRef()

// Ref를 적용하고싶은 input태그(=접근하고싶은 태그)
<input type="text" ref={this.inputRef}/>

//태그에 접근해서 실행시킬 함수
componentDidMout(){
		console.log("마운트 됨")
		this.inputRef.current?.focus()
	}

함수형 컴포넌트 useRef()

함수형 컴포넌트에서는 useRef 훅을 이용해 특정 태그에 접근

// 훅 임폴트
import {useRef} from 'react'

//Ref코드 생성
const inputRef = useRef()

// Ref를 적용하고 싶은 input태그(=접근하고 싶은 태그)
<input type="text" ref={inputRef}/>

//태그에 접근해서 실행시킬 함수 _ useEffect참고는 바로 아래에서!
useEffect(()=>{
		console.log("마운트 됨")
		inputRef.current?.focus()
	})

this 바인딩( .bind(this) )

this는 실행하는 주체에 따라서 다르게 나온다
이렇게 바뀌는 this를 동적 this라고 하는데,
따라서 onClickCouter 를 클릭시에 this가 onClickCouter로 바뀌게 된다.

변화하는 this를 class로 고정하기 위해서는 this를 바인딩해주거나 화살표 함수를 써줘야 한다

  • 이렇게 바인딩 과정을 거쳐서 고정된 this를 렉시컬 this라고 함

class 컴포넌트의 생명주기(Life Cycle)

클래스형 컴포넌트에 있는 생명주기 메서드들

  1. 그리기
    => render
  2. 그리고 난 뒤
    => componentDidMount
  3. 그리고 난 뒤 변경됐을 때
    => componentDidUpdate
  4. 그리고 난 뒤 사라질 때
    => componentWillUnmount
import { Component, createRef } from "react";
import Router from "next/router";

export default class CounterPage extends Component {
  state = {
    count: 99,
  };

  componentDidMount() {
    console.log("마운트됨!!!");
    // 포커스 깜빡깜빡
  }

  componentDidUpdate() {
    console.log("수정되고 다시그려짐!!!");
  }

  componentWillUnmount() {
    console.log("컴포넌트 사라짐!!!");
    // 채팅방 나가기
    // api 요청!!!
  }

  onClickCounter = () => {
    this.setState((prev) => ({
      count: prev.count + 1,
    }));
  };

  onClickMove() {
    Router.push("/");
  }

  render() {
    return (
      <div>
        <div>현재카운트: {this.state.count}</div>
        <button onClick={this.onClickCounter}>카운트 올리기!!!</button>
        <button onClick={this.onClickMove}>나가기!!!</button>
      </div>
    );
  }
}

그렇다면 함수형 컴포넌트에서의 생명주기 관련 훅은?
=> useEffect

함수형 컴포넌트의 생명주기 훅 useEffect

import { useEffect, useState } from "react";
import { useRouter } from "next/router";

export default function CounterPage() {
  const router = useRouter();

  const [count, setCount] = useState(99);

  // componentDidMount() {
  //   console.log("마운트됨!!!");
  //   // 포커스 깜빡깜빡
  // }

  // componentDidUpdate() {
  //   console.log("수정되고 다시그려짐!!!");
  // }

  // componentWillUnmount() {
  //   console.log("컴포넌트 사라짐!!!");
  //   // 채팅방 나가기
  //   // api 요청!!!
  // }

  //DidMount
  useEffect(() => {
    console.log("마운트됨!!!");
  }, []);
  // [] => "의존성 배열" 이라고 부른다
  // 의존성 배열[]에 아무것도 넣지 않으면 Mount시에만 렌더해주고 끝나게 됨 (처음 1번만 실행됨)
  // [] 안에 있는 값이 변경될때마다 다시 실행됨

  //DidUpdate
  useEffect(() => {
    console.log("수정되고 다시그려짐!!!");
  });
  // 의존성 배열이 없기 때문에 뭐 하나라도 바뀌면 무조건 다시 실행됨
  // componentDidUpdate는 뭐가 바뀔때만 실행되지만, 얘는 처음에도 한 번 실행되는 차이점이 있음

  //WillUnmount 와 비슷함
  useEffect(() => {
    console.log("수정하고 다시 그려짐!!");

    //이부분이 끝나고 진행할 것들
    return () => {
      console.log("컴포넌트 사라짐!!!");
    };
  }, []);

  // 1. 하나로 합치기 가능
  // useEffect(()) => {
  //   console.log("마운트됨!!!")
  //   //포커스 깜빡깜빡

  //   return () => {
  //     console.log("컴포넌트 사라짐!!");
  //     //채팅방 나가기
  //     //api 요청!!
  //   }
  // }, []);

  // 2. useEffect의 잘못된 사용 예제
  // 1) 추가렌더링, 2) 무한루프
  // useEffect(() => {
    setCount((prev) => prev + 1);
  }, [count]);

  const onClickCounter = () => {
    setCount((prev) => prev + 1);
  };

  const onClickMove = () => {
    router.push("/");
  };

  return (
    <div>
      <div>현재카운트: {count}</div>
      <button onClick={onClickCounter}>카운트 올리기!!!</button>
      <button onClick={onClickMove}>나가기!!!</button>
    </div>
  );
}
  • useEffect의 실행 시점
    => 생명주기 메서드,훅 은 기본적으로 렌더(화면그리기) 이후에 실행됨
    따라서 useEffect와 lifecycle 메서드는 렌더 이후에 실행된다!

useEffect 사용시 주의 사항

→useEffecrt 내에서 setState를 사용할때는 정말 필요한 경우가 아니라면 지양

컴포넌트가 마운트된 이후에 setState를 적용하게 되면,
1. state가 변경되고,
2. 변경된 state로 컴포넌트가 다시그려지게(=리렌더)됨

즉, useEffecrt 내에서 setState를 사용하게 되면 불필요한 리렌더나 무한루프를 일으키게 되고 성능면에서 비효율적이게 된다!

++
댓글 삭제할 때 모달로 변경하면 오류나는거 해결하긔 (해결)

포트폴리오에 랜딩페이지 만들기 ! (사이트 처음 들어갔을때 나오는 페이지) (해결)

자유게시판 디자인 생각해보기 !

노션 블로깅 플러스 주제 보고 블로깅하기!

profile
어제보다 오늘 발전하는 프론트엔드 개발자

0개의 댓글