CS 대비/FrontEnd Part

[React] React Hooks 정리

JellyApple 2023. 12. 23. 01:01

 

 

그동안 애매하게 알았거나 잘 몰랐던 것들과 알아도 복습하자는 의미로 자주 사용했던 것들을 한번 정리해봤다.

1. useState 
: 동적인 값을 상태(state)라고 하는데 이를 관리해주는 함수다. 이 함수를 통해 컴포넌트에서 상태를 관리할 수 있다.

import React , {useState} from 'react';
const [number , setNumber] = useState(0);

 

2. useRef 

: 자바스크립트에서 querySelector , getElementById 등을 통해 특정 DOM을 선택해주었다. React에서도 이 처럼 저장공간 또는 DOM요소에 접근하기 위해 사용되는 것이 바로 useRef이다.  .current 를 붙여서 사용한다! 

=> useRef로 관리하는 변수는 값이 바뀐다고 해서 컴포넌트가 리렌더링 되지 않는다!

ex) 웹 사이트 들어갈 때 로그인 화면에 들어가자마자 아이디 input에 포커스 되어 있는 경우

import React, { useState, useRef } from 'react';

function InputSample() {
  const [inputs, setInputs] = useState({
    name: '',
    nickname: ''
  });
  const nameInput = useRef();

  const { name, nickname } = inputs; // 비구조화 할당을 통해 값 추출

  const onChange = e => {
    const { value, name } = e.target; // 우선 e.target 에서 name 과 value 를 추출
    setInputs({
      ...inputs, // 기존의 input 객체를 복사한 뒤
      [name]: value // name 키를 가진 값을 value 로 설정
    });
  };

  const onReset = () => {
    setInputs({
      name: '',
      nickname: ''
    });
    nameInput.current.focus();
  };

  return (
    <div>
      <input
        name="name"
        placeholder="이름"
        onChange={onChange}
        value={name}
        ref={nameInput}
      />
      <input
        name="nickname"
        placeholder="닉네임"
        onChange={onChange}
        value={nickname}
      />
      <button onClick={onReset}>초기화</button>
      <div>
        <b>값: </b>
        {name} ({nickname})
      </div>
    </div>
  );
}

export default InputSample;

 

3. useEffect() 
: 컴포넌트가 마운트 됐을 때, 사라질 때 , 업데이트 될 때, 즉 렌더링 될 때마다 특정 작업을 실행할 수 있도록 하는 React Hook이다. 

import React , {useEffect} from 'react';

// 가장 처음 렌더링 될 때 한 번만 실행하고 싶을 때
useEffect(()=>{
    console.log('마운트 될 때만 실행');
    },[]);
    
// 렌더링 될 때마다 실행
useEffect(()=>{
    console.log('렌더링 될 때마다 실행');
    });

 

4. useMemo()

: 성능 최적화를 위해 연산된 값을 재사용할 수 있게 도와주는 Hook이다. 값은 변하지 않았는데 다른 input 값들이 바뀔 때 쓸데없이 호출해주는 것을 방지 한다. 

  const count = useMemo(() => countActiveUsers(users), [users]);

 

5. useCallback() 
: 특정 함수를 새로 만들지 않고 재사용하고 싶을 때 사용, 즉 컴포넌트가 처음 렌더링 될 때만 이 함수 객체를 만들어서 이  onChange 를 초기화해주고 이후 렌더링에 onChange 변수가 새로운 함수 객체를 다시 할당받는 것이 아니라 이전에 이미 할당받은 함수 객체를 계속해서 가지고 있으면서 재 사용하는 것을 말한다. 또한 첫 번째로 콜백함수를 받고  의존성 배열을 두 번째 인자로 받는다. 

  const onChange = useCallback(
    e => {
      const { name, value } = e.target;
      setInputs({
        ...inputs,
        [name]: value
      });
    },
    [inputs]
  );

 

6. React.memo 

: 컴포넌트의 props가 바뀌지 않았다면 리렌더링을 방지하여 컴포넌트의 리렌더링 성능을 최적화 해줄 수 있는 함수다. 사용법은 그냥 감싸주면 된다.

import React from 'react';

const CreateUser = ({ username, email, onChange, onCreate }) => {
  return (
    <div>
      <input
        name="username"
        placeholder="계정명"
        onChange={onChange}
        value={username}
      />
      <input
        name="email"
        placeholder="이메일"
        onChange={onChange}
        value={email}
      />
      <button onClick={onCreate}>등록</button>
    </div>
  );
};

export default React.memo(CreateUser);

 

7. useReducer()

: useState 말고도 상태를 관리할 때 사용할 수 있는 다른 함수, 이 함수를 사용하면 컴포넌트의 상태 업데이트 로직을 컴포넌트에서 분리할 수 있다. 그래서 바깥에 작성할 수 있다.

  reducer : 현재 상태와 액션 객체를 파라미터로 받아와서 새로운 상태를 반환해 줌

function reducer(state, action) {
  // 새로운 상태를 만드는 로직
  // const nextState = ...
  return nextState;
}

 

const [state, dispatch] = useReducer(reducer, initialState);

 

사용법은 아래와 같다. Redux 에서 봤던 틀과 흡사하다.

import React, { useReducer } from 'react';

function reducer(state, action) {
  switch (action.type) {
    case 'INCREMENT':
      return state + 1;
    case 'DECREMENT':
      return state - 1;
    default:
      return state;
  }
}

function Counter() {
  const [number, dispatch] = useReducer(reducer, 0);

  const onIncrease = () => {
    dispatch({ type: 'INCREMENT' });
  };

  const onDecrease = () => {
    dispatch({ type: 'DECREMENT' });
  };

  return (
    <div>
      <h1>{number}</h1>
      <button onClick={onIncrease}>+1</button>
      <button onClick={onDecrease}>-1</button>
    </div>
  );
}

export default Counter;

 

8. useContext()

: 기존의 React에 있던 Context를 더 편하게 사용할 수 있게 해주는 역할을 한다. 여기서 Context란 공식 문서에서는 

"context를 이용하면 단계마다 일일이 props를 넘겨주지 않고도 컴포넌트 트리 전체에 데이터를 제공할 수 있다." 라고 되어 있다. 

context API 
 - createContext : context 객체 생성
 - Provider: 생성한 context를 하위 컴포넌트에게 전달하는 역할
 - Consumer : context의 변화를 감시하는 컴포넌트

// App.js
import React, { createContext } from "react";
import Children from "./Children";

// AppContext 객체를 생성한다.
export const AppContext = createContext();

const App = () => {
  const user = {
    name: "김채원",
    job: "가수"
  };

  return (
    <>
      <AppContext.Provider value={user}>
        <div>
          <Children />
        </div>
      </AppContext.Provider>
    </>
  );
};

export default App;
// childern.js
import React from "react";
import { AppContext } from "./App";

const Children = () => {
  return (
      <AppContext.Consumer>
        {(user) => (
          <>
            <h3>AppContext에 존재하는 값의 name은 {user.name}입니다.</h3>
            <h3>AppContext에 존재하는 값의 job은 {user.job}입니다.</h3>
          </>
        )}
      </AppContext.Consumer>
  );
};

export default Children;

이렇게 부모에서 Provider로 감싸주고 children에서 Consumer로 변화를 감지해준다. 한 편 useContext를 적용하면 
Children.js를 아래처럼 바꿔줄 수 있다. Consumer로 감 싸줄 필요 없이 간결하게 사용 가능하다.

import React, { useContext } from "react";
import { AppContext } from "./App";

const Children = () => {
  // useContext를 이용해서 따로 불러온다.
  const user = useContext(AppContext);
  return (
    <>
      <h3>AppContext에 존재하는 값의 name은 {user.name}입니다.</h3>
      <h3>AppContext에 존재하는 값의 job은 {user.job}입니다.</h3>
    </>
  );
};

export default Children;

 

9. useSearchParams() / useLocation()
: 쿼리스트링을 다룰 때 필요한 함수다. 쿼리스트링은 문자열의 형태를 띄며 key=value로 표현한다. ?로 시작임을 알리고 &로 구분을 해준다. react-router-dom에서 쿼리스트링을 가져올 수 있는 hook은 useLocation , useSearchParams 두 개가 있다.
1) useLocation() : 현재의 Location 객체를 반환함

// 해당 훅을 호출하고
import { useLocation } from "react-router-dom"

// 컴포넌트 안에서 데이터를 변수에 담고 확인
const location = useLocation();
console.log(location); 

console.log(location.search); // => ?sort=popular

2) useSearchParams() : 위 location에서 일일이 뽑아서 사용하기엔 복잡할 때가 있을 것이다. 그래서 이를 좀 더 쉽게 가져올 수 있게 해주는 hook이다. 사용 할 수 있는 메서드는 크게 값을 읽어오는 메서드와 값을 변경하는 메서드가 있다.
값을 읽어오는 메서드
 - searchParams.get(key) : 특정한 key의 value를 가져오는 메서드 만약 여러 개면 제일 먼저 나온 value만 리턴

 - searchParams.getAll(key) : 특정 key에 해당하는 모든 value를 가져오는 메서드

 - searchParams.toString() : 쿼리 스트링을 string 형태로 리턴

값을 변경하는 메서드
 - searchParams.set(key, value) : 인자로 전달한 key 값을 value로 설정, 이미 존재했다면 기존 값은 삭제

 - searchParams.append(key, value) : 기존 값을 변경하거나 삭제하지 않고 추가하는 방식

실제 사용 예시

// src/List.js
// 처음 유저가 /list?offset=10&limit=10 이렇게 접속한다고 가정

import React, { useEffect, useState } from 'react';
import { useSearchParams } from 'react-router-dom'; // 훅을 호출하고

const List = () => {
	const [searchParams, setSearchParams] = useSearchParams(); // 쿼리 스트링을 searchParams 형태로 가져오고
	 const offset = searchParams.get('offset'); // offset 값 변수에 저장
	 const limit = searchParams.get('limit'); // limit 값 변수에 저장
	 return (
		 <section>
		     <h1>This is Posts</h1>
		 </section>
	 );
};

export default List;

 

10. useParams()

: 쿼리와 다르게 파라미터 정보를 가져와 활용하고 싶을 때 사용한다.

import React from 'react';
import { useParams } from 'react-router-dom';

const test = () => {
  let { params } = useParams();

  return (
    <div className="test">
      <p>현재 페이지의 파라미터는 { params } 입니다.</p>
    </div>
  )
}

export default test;

 

※ 참고자료
https://react.vlpt.us/basic/10-useRef.html

 

10. useRef 로 특정 DOM 선택하기 · GitBook

10. useRef 로 특정 DOM 선택하기 JavaScript 를 사용 할 때에는, 우리가 특정 DOM 을 선택해야 하는 상황에 getElementById, querySelector 같은 DOM Selector 함수를 사용해서 DOM 을 선택합니다. 리액트를 사용하는

react.vlpt.us

https://velog.io/@jminkyoung/TIL-6-React-Hooks-useContext-%EB%9E%80

 

[TIL #6] React (Hooks) - useContext 란?

useContext는 기존의 React에 존재하는 Context를 더 편하게 사용할 수 있게 해주는 역할을 한다. 따라서 useContext에 대해서 다루기 전에 우선 React에서 Context란 무엇인지부터 다뤄야 한다! 🏃‍♀️React

velog.io

https://velog.io/@rayong/%EB%A6%AC%EC%95%A1%ED%8A%B8-%EA%B8%B0%EC%B4%88-%EC%BF%BC%EB%A6%AC-%EC%8A%A4%ED%8A%B8%EB%A7%81-useSearchParams

 

리액트 기초, 쿼리 스트링, useSearchParams

위코드에서 공부하며 정리한 내용입니다.쿼리 스트링은 URL 의 한 부분으로, 요청하는 URL 에 부가정보를 포함할 때 사용합니다. 기존 URL 은 단순한 형태의 요청과 응답을 주고 받았지만 쿼리 스

velog.io