[리액트 스터디] useState / useEffect

경미·2023년 2월 6일
0

REACT-STUDY

목록 보기
4/7

Hooks?

  • Hooks는 일반 Javascript 함수이다. 그래서 Hooks를 활용하는 custom hooks를 만들어 상태를 가지는 로직을 함수로 쉽게 분리할 수 있다.

Hooks가 제공하는 내장 API(즉, 기본 Hook들에는 useState, useEffect, useContext가 있다.)

useState

state?

  • 계속해서 변화하는 특정 상태. 상태에 따라 각각 다른 동작을 함

useState?

  • 함수형 컴포넌트에서 상태값을 관리하게 해준다. initialValue 파라미터(인자)로 받고, state와 state를 변경할 setState함수 반환함

    🙋‍♀️배열의 비구조화 할당 통해서 받는것이므로, state나 setState 이름은 임의로 정할 수 있음

어떻게 진행되냐면

1️⃣: 최초로 렌더링 하는 동안, 반환된 state는 첫번째 전달된 인자(initialValue)의 값과 같음
2️⃣: setState 함수는 state 갱신할때(바뀔때!!!!) 사용함. 새 state 값 받아서 컴포넌트 리렌더링을 큐(대기줄이라고 생각하자)에 등록!
3️⃣: 다음 리렌더링 시에 useState를 통해 반환받은 첫번째 값은 항상 최신 state가 됨(클래스형 컴포넌트에서 setState 하면 병합되지만, 함수형 컴포넌트에서는 이전 상태값 지움)

가장 보편적인 예제인 Counter.js

import React, { useState } from "react";
//useState라는 메서드를 이용해서 사용할거니까 react import 해줘야함!

/*
useState() 리액트 메서드!
- 배열을 반환함
- 배열의 비구조화 할당 통해서 count(값으로 사용), setCount(상태변화함수)
- setCount로 상태를 변화시킬수(업데이트) 할수 있다는 뜻!
- useState(숫자)=> 숫자는 초기값!

*/

const Counter = () => {
  const [count, setCount] = useState(0); // 초기화 해준것
  // 버튼 누르면 증가, 감소하는 함수 만들어서 onclick 이벤트로 추가해줘야함
  const onIncrease = () => {
    setCount(count + 1); //++은 안됨
  };
  const onDecrease = () => {
    setCount(count - 1);
  };
  /*
    0에서 출발 -> 1씩 증가하고 -> 1씩 감소하는 : count 상태!
    */
  return (
    <div>
      <h2>{count}</h2>
      <button onClick={onIncrease}>+</button>
      {/* 카멜케이스로사용하고, {}에 함수이름 넣으면된다! */}
      <button onClick={onDecrease}>-</button>
    </div>
  );
};

useEffect

  • useEffect는 컴포넌트의 상태값 변화에 따라 컴포넌트 내부에서 변경이 이루어져야 되는 것들을 처리할 수 있다!

useEffect

  • 첫번째 인자로 콜백함수를 받고, 두번째 인자로는 Dependency Array를 받는다(두번째 인자 없으면, 컴포넌트가 업데이트 되는 시점에 제어)



=> 빈배열이라면, 처음 마운팅 될때만 실행!

import React, { useEffect, useState } from "react";

const LifeCycle = () => {
  const [count, setCount] = useState(0);
  const [text, setText] = useState("");

  /* 컴포넌트가 mount(시작) 되는 시점 제어 */
  useEffect(() => {
    console.log("Mount!");
  }, []);
  /*카운트를 입력해도, mount 안찍히는걸 보면 
  두번째 인자에 [](빈배열)넣어주고, 첫번째 인자에 콜백함수(안에 수행하고싶은 코드 넣어주기)
  */

  /* 컴포넌트가 업데이트 되는 시점 제어 : 두번째 인자 작성 안하기*/
  useEffect(() => {
    console.log("Update!");
  });

  /* dependency array의 값이 변화할때마다 찍히는 시점 
  => 즉 잘 활용하면 감지하고 싶은 값이 변화하는 순간에만 콜백함수 수행할 수 있다는 말
  */
  useEffect(() => {
    console.log(`${count}번째 업데이트`);
    if (count > 5) {
      alert("count는 5를 넘을 수 없습니다. 따라서 1로 초기화 합니다.");
      setCount(1); //바꿔주고 싶은 값을 입력하면됨
    }
  }, [count]);

  useEffect(() => {
    console.log(`text is update : ${text}`);
  }, [text]);

  return (
    <div style={{ padding: 20 }}>
      <div>
        {count}
        <button onClick={() => setCount(count + 1)}>+</button>
        <div>
          <input value={text} onChange={(e) => setText(e.target.value)}></input>
        </div>
      </div>
    </div>
  );
};
export default LifeCycle;

Unmount 되는 시점 제어

  • 리턴에 콜백함수 넣기!
import React, { useState, useEffect } from "react";
export const Timer = () => {
  useEffect(() => {
    const timer = setInterval(() => {
      console.log("타이머 돌아가는중..");
    }, 1000);

    //useEffect의 리턴값으로 정리할 함수를 써주면됨!(unMount, 즉 화면에서 사라질때 실행)
    return () => {
      clearInterval(timer);
      console.log("타이머 종료");
    };
  }, []);
  return (
    <>
      <span> 타이머를 시작합니다. 콘솔을 보세요!</span>
    </>
  );
};
const UesEffect = () => {
  const [toggle, setToggle] = useState(false);
  const handleTogle = () => {
    setToggle(!toggle);
  };
  return (
    <div>
      {toggle && <Timer />}
      <button onClick={handleTogle}>Toggle Timer</button>
    </div>
  );
};

export default UesEffect;

useEffect 3가지 방법 정리

1) dependency가 없는 방법

=> 어떤 state의 변수든, 값이 변경된것 인지하고 실행함(업데이트 될때마다 실행)

2) 대괄호 이용

=> 처음 mount 되는 시점만 실행!

3) 대괄호 안에 특정 변수(들)을 지정하는 방법

=> 대괄호 안에 지정된 변수 혹은 오브젝트가 변하지 않으면 useEffect는 실행되지 않는다.

study

리액트에서의 불변성

=> 복사본을 만들어서 사용해야한다.(참조타입은 콜스텍에 메모리힙의 주소만을 저장하고 메모리 힙에 저장, 변경되기 때문에!) , 얕은 복사와 깊은 복사와 관련있다!

=> 간단하게 요약하면 리액트 상태 업데이트의 원리 때문임.

setState는 비동기 함수이다

=> batch라는 특징

sideEffect

unMount인경우 => 주로 사용하는 상황

피큐레잇

profile
개발이 재밌어지도록!

0개의 댓글