Day-16 inputs 최적화, class? this?, Life Cycle(생명주기), useEffect, useRef

이영주·2022년 5월 30일
0
post-custom-banner

2일차에 잠깐 맛보기했던 클래스형과 함수형에 대해서 오늘은 더 자세히 알아보게 되었다. 클래스형에서 함수형으로 많이 사용되고 있는 추세라지만 클래스형도 알아야 코드를 읽는 범위가 넓어지니까 잘 비교해보는 것이 좋을 것 같다!
그나저나 이 친구들도 생명주기라는게 있다던데 컴퓨터 주제에 사람같은 느낌적인 느낌.. 갑자기 동질감이 느껴지니까 좀 더 친해져 보기로..ㅎ

inputs 최적화

inputs을 이용하여 state와 함수를 간단하게 표현할 수 있다.

const [writer, setWriter] = useState("");
const [title, setTitle] = useState("");
const [contents, setContents] = useState("");

위의 state를 하나로 합치기 위해 inputs을 이용하여 하나의 객체로 묶어준다.

const [inputs, setInputs] = useState({
    writer: "",
    title: "",
    contents: "",
  })

setInputs에는 각각의 키에 맞는 값이 들어가게 되는데 같은 객체에서 가져오기 때문에 동일해져 아래 사진처럼 스프레드 연산자(...)를 사용하여 하나로 표현한다.

return부분에는 writer, title, contents 각각의 id를 지정 후 onChange 함수의 이름을 onChangeInputs으로 동일하게 변경해준 뒤 하나의 함수만 남긴다.

이때 객체에서 키는 중복이 될 수가 없기 때문에 event.target.id로 가져오게 되는데 객체의 키에는 . 을 사용하지 못하기 때문에 대괄호[ ]로 묶어주어야 한다!!

대괄호로 묶어준 키에는 변수가 들어갈 수 있게 되어 event.target으로 들어온 writer, title, contents등이 들어올 수 있게 된다.
📌 참고: 위에서 사용한 대괄호는 배열이 아님을 주의해야한다!!!!

이렇게 inputs을 사용하여 많은 함수를 하나로 줄일 수 있는 최적화를 알아보았다!


Class? This?

class란 물건을 만드는 설명서이다. 설명서대로 만들어진 것은 new로 표현한다.

만드는 방법이 있는 설명서에는 객체이기 때문에 .을 이용하여 값을 추출한다.
(객체는 인스턴스라고도 부르며, .뒤에를 메소드라고 부른다.)

이러한 클래스형 컴포넌트에는 function, const, let 등이 사용되지 않는다❌

function을 쓰는 함수형 컴포넌트와는 다르게 클래스형 컴포넌트는 class와 extends Component를 함께 사용한다.

*함수형 컴포넌트
export default function ClassCounterPage() {
	return(
   )
}

*클래스형 컴포넌트
export default class ClassCounterPage extends Component{
	render() {
  		return(
        )
  	}
}

extends Component로 실행된 클래스형 컴포넌트 안에는 react에서 제공하는 기능을 상속받기 때문에 내장된 setState 등은 선언을 해주지 않아도 된다.

하지만 이를 사용하기 위해서는 import { Component } from "react"를 해주어야 한다.

클래스형은 객체로 이루어져있다고 위에서 언급했듯이 사용을 하기 위해서는 this를 이용해야 한다.

this란 클래스 함수 그 자체를 말한다.
this. 을 사용하여 객체의 키나 값을 가져온다.

하지만 this는 어떤 주체가 실행시켰느냐에따라 결과가 달라지기 때문에 문제가 발생하기도 한다.

위의 사진의 경우 {this.state.count}의 this는 최상위 주체인 클래스형 함수에서 가져오기 때문에 값이 잘 나오지만 {this.onClickCounter}의 경우에는 onClick을 하는 주체로 변경되기 때문에 실행되지 않는다.

이러한 문제를 해결하기 위해 this를 최상위 주체로 보내는 2가지 방법
1. 화살표 함수로 만들어주기

onClickCounter = () => {}

2. this 바인딩 시켜주기

<button onClick={this.onClickCounter.bind(this)}>카운트 올리기</button>

둘 중 하나의 경우로 사용하면 되는데 화살표 함수로 표현하는 것이 더 효율적일 것 같다는 개인적인 의견이다!


Life Cycle(생명주기)

클래스형 컴포넌트에는 특정 시점에 코드가 실행되도록 설정하는 생명주기라는 것이 있다.
이를 표현하는 매서드가 4가지 단계로 나뉜다.

  1. 그리기(render) ex. 인풋창 만들기
  2. 그리고 난 뒤(componentDidMount) ex. 포커스 깜빡깜빡
  3. 그리고 난 뒤 변경되었을 때(componentDidUpdate)
  4. 그리고 난 뒤 사라질 때(componentWillUnmount)

이를 함수형 컴포넌트에서 사용할 때는 useEffect를 사용한다.

useEffect

useEffect는 한번은 꼭 실행되는 함수이며

useEffect(() => {

}, [ 의존성 배열 ])

위와 같이 사용되는데 대괄호 안에 의존성 배열에 들어가 있는 값에 따라서 실행되며,
비어있고 대괄호만 있으면 처음 한번만 실행되고 다시는 실행되지 않으며,
아예 대괄호조차 없으면 종료되지 않고 계속 실행된다.

클래스형 컴포넌트의 componentWillUnmount를 함수형 컴포넌트를 사용할 때는 다른 것과는 다르게 return을 적어주어야 한다!

useEffect(() => {
  return () => {
  
  }
}, [ 의존성 배열 ])

이렇게 useEffect를 사용할 때 잘못된 2가지 방법이 있는데

1.추가렌더링
useEffect 사용시 setState를 사용할 경우 렌더링 후 다시 렌더링이 되는 비효율적인 면을 가진다.
따라서 useEffect에는 setState를 사용하지 않는 것이 좋다.

2.무한루프
setState와 의존성배열에 값을 잘못 사용할 경우 계속 실행되는 무한루프가 될 수 있기 때문에 조심해야 한다.

useRef

react에서 특정태그에 접근할 때 Ref를 이용하여 태그를 직접 변수에 저장하도록 할 수 있다.

클래스형 컴포넌트에서는 createRef() 매서드를 이용하여 특정 태그에 접근할 수 있으며,
함수형 컴포넌트에서는 useRef 훅을 이용하여 특정 태그에 접근할 수 있다.

* 클래스형 컴포넌트
	import {crateRef} from 'react'

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

	<input ref={this.inputRef} /> //Ref에 적용할 input태그
      
    this.inputRef.currnet?.focus() //태그에 실행시킬 함수
    
    
* 함수형 컴포넌트
	import {useRef} from 'react'

	const inputRef = useRef() //Ref코드 생성하기
    
    <input ref={inputRef} /> //Ref에 적용할 input태그
      
   	inputRef.current?.focus() //태그에 실행시킬 함수(useEffect 사용)
    

Ref는 처음 초기값이 null이며,
함수형 컴포넌트로 이미지를 업로드하는 예를 들어보자

const fileRef = useRef(null) //fileRef 변수 만들기
fileRef.current.click() //기존 타입인 file이 아닌 변수 fileRef 클릭하도록 설정

//fileRef 변수를 return의 파일 태그랑 연결하기!

<input type="file" ref={fileRef} />

간단하게는 이렇게 표현해 볼 수 있고
기존 타입인 file을 클릭하는 대신 변수 fileRef를 굳이 만드는 이유는 왜그럴까?

기존 타입은 css로 꾸미기가 힘들어서 변수를 만들어 변수 자체를 눈에만 안보이게 display: none으로 설정 후 변수를 감싸는 것을 만들어 그것을 디자인하고 클릭했을때는 변수가 클릭된것 처럼 보이게하는 효과를 주기 위해서이다.

profile
= ["꼼꼼한", "프론트엔드 개발자"]
post-custom-banner

0개의 댓글