본문 바로가기

CodeTech/React

React Hooks - 1 [useState, useEffect, useRef]

React Hook

ko.reactjs.org/docs/hooks-intro.html

 

Hook의 개요 – React

A JavaScript library for building user interfaces

ko.reactjs.org

 

 

hook이라는 개념이 나온이유

react는 컴포넌트를 재사용하려면 사용자가 어느정도까지 재사용을 할 것인지, 어느 부분을 재사용하는지

명시해 놓지 않는다. 따라서 여러 패턴이 필요하며 패턴을 사용할 때마다 컴포넌트를 재구성하는 것이 필요하고

이렇게 변경된 코드들은 같은 일을 하지만 다른 모습을 하고 있기에 코드를 추적하기어렵다.

 

특히나 컴포넌트의 생명주기와 관련되어서는 상태변화에 따라서 해당 함수가 만들어진 목적과 다르게

사용되는 경우가 매우 많다.

예) componentDidMount, componentDidupdate같은 메서드들은 실행순서만이 고려되어

전혀 상관없는 로직이 들어가는 경우가 많고 이로인해 버그 생성률인 높아진다.

 

Hook을 통해 로직에 기반을 둔 작은 메서드 들로 컴포넌트의 기능을 나눌수 있다.

 

즉, Hook은 더이상 class기반으로 react기능들을 의존하지 않고 좀더 로직과 기능분배를 목적으로 

사용된다.

 

useState() 

- state를 관리할때에 필요한 함수이다.

import React, {useState} from "react";
import "./styles.css";

export default function App() {
  const [count, setCount] = useState(0);
  const incrementCount = () => {setCount(count + 1)};
  const decrementCount = () => {setCount(count - 1)};
  return (
    <div className="App">
      <h1>Count {count}</h1>
      <button onClick = {incrementCount}>incrementCount</button>
      <button onClick = {decrementCount}>decrementCount</button>
    </div>
  );
}

위 코드 환경은 간단하게 코드를 연습할수 있는 codeSandbox라는 곳이다.

codesandbox.io/dashboard/home?workspace=b8f69121-500c-4f25-8f33-98f07c3c1112

 

CodeSandbox

CodeSandbox is an online editor tailored for web applications.

codesandbox.io

위 코드에서 useState()의 인수가 배열인데 인덱스가 2개인 배열이다.

첫 원소는 state의 변수, 두번째 원소는 state의 변수를 설정할 set메소드이다.

이렇게 설정하면 해당 state변수만을 set하는 전용 메소드가 만들어진다.

 

이렇게 쉽다니!?!

 

마치 getter, setter같은 개념같지 않나, 이로서 state접근에 대한 보호가 생긴다.

해서 해당 익명함수는 setCount를 사용함으로서 count state변수를 수정한다.

- > 이름은 관계가 없다. count와 setCount는 useState(0) 함수로서 짝이 되었고

0라는 값은 count의 초기값이 되었다.

 

useEffect()

- class 컴포넌트 기준으로 컴포넌트가 랜더링 되기전에 수행하는 과정을 넣을 수 있다.

- componentDidMount() 함수 같은 역할이다.

- 따라서 웹페이지의 state가 변하는것을 감지하고 변할때마다 렌더링을 새로하게 된다.

특정 state 변수만 변하는 것을 감지해서 렌더링 되도록 설정 해줄수도 있다.

 

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

export default function App() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  );
}

- 위 코드에서 useEffect()함수를 사용해서 함수가 실행되기전에 브라우저의 탭 타이틀을 

you clicked ${count} times가 되게 만들었다. 

 

- 이부분에는 컴포넌트가 실행되기전 api를 불러온다던가, 어떠한 작업을 수행한 후에 

return 이 되게 한다. 리액트는 우리가 넘긴 함수를 '기억' 했다가 DOM업데이트 (return) 을

수행한 후 또 불러낸다. 이러한 메소드를 'effect' 라고 한다.

useEffect는 랜더링 이후 매번 수행된다. 모든 업데이트 과정에서도 수행된다.

위 경우들을 보면 알겠지만 Hook들은 각각의 컴포넌트마다 같은 역할을 하지만 구분되어진다.

(컴포넌트 안에 있는 경우에서는 말이다.)

 

특정 state변수만 감지하여 렌더링하기

- 위코드는 전체 스테이트 변수를 감지한다. 따라서 아래 와 같이 바꿀수 있다.


  useEffect(() => {
    document.title = `You clicked ${count} times`;
  }, [count]);

- 위 코드는 계속해서 끊임 없이 state변수들이 변하면 계속 해서 페이지가 렌더링 된다.

 

첫 페이지 렌더링을 할때 한번만 실행하기

- 한번만 렌더링 하게 할수도 있다.

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  }, []);

useEffect(  함수, []) 이렇게 빈칸을 넣어놓으면 첫 렌더링후 한번만 렌더링 하도록 만들수 있다.

 

이외에 사람들은 자신이 만든 훅들을 사용할 수있다.

 

 

 

useRef()

- 원하는 DOM 혹은 컴포넌트에 접근 가능하게 해주는 시스템이다.

보통 원하는 DOM 이나 컴포넌트에는 className을 붙여버리는데 그렇게 하지 않고

reference를 붙여버림으로서 해당 ref가 붙은 element를 가르킨다.

 

function TextInputWithFocusButton() {
  const inputEl = useRef(null);
  // inputEl에 null 값을 가진 ref객체를 생성해서 넣어줬다.
  const onButtonClick = () => {
    // current라는 속성은 inputEl이라는 ref를 가진 element를 반환한다.
    inputEl.current.focus();
  };
  return (
    <div>
    	// ref를 가진 element!
      <input ref={inputEl} type="text" />
      <button onClick={onButtonClick}>Focus the input</button>
    <div/>
  );
}

- 위 코드에서 inpuEl 이라는 ref를 가진 객체를 생성하고 해당 ref를 가진 element를 current 속성으로 가르켜서 원하는 

element에 ref를 넣고 다루는 예를 보았다. 

 

ref를 변수로 사용하기

function TextInputWithFocusButton() {
  const count = useRef(null);
  // inputEl에 null 값을 가진 ref객체를 생성해서 넣어줬다.
  
  count.current = 1;
  console.log(count.current+1);
 }

이렇게 useRef로 변수를 선언할수도 있는데 이때 해당변수는 바로바로 페이지에 적용이된다.

useEffect에 들어가는 state변수의 렌더링은 state변수가 변하면 한번의 렌더링을 새로 고쳐 변하는 반면

useRef로 선언한 변수는 새로 렌더링 되지 않고 바로 적용되나, 렌더링 감지가 되지 않는다.

 

이렇게 사용되는 useRef는 보통 페이지 스크롤등에 사용된다.

 

'CodeTech > React' 카테고리의 다른 글

React - [naming]  (0) 2020.12.11
React - [onclick - history]  (0) 2020.12.11
ReactNative - 3 [배포]  (0) 2020.11.29
ReactNative - 2 [View]  (0) 2020.11.28
React Native - 1 [설치]  (0) 2020.11.28