프론트엔드 - 20

송현섭 ·2023년 4월 20일

프론트엔드

목록 보기
20/24
post-thumbnail

Destructuring (비구조화 할당 / 구조분해 할당)




객체 구조분해할당


const child = {
	name : “철수”,
	age : 58,
	school : “개발 공장”
}
  • 위와 같은 형태의 객체는 구조 분해할당을 통해 일부 또는 모든 값을 변수에 담아 꺼낼 수 있음


//객체의 비구조화 할당
const {name, age, school} = child
  • 선언부에 중괄호를 사용하고, child라는 객체의 key값을 변수명으로 사용해서 가져올 수 있음
    *가져올 때 각 변수의 순서는 중요하지 않지만, 변수의 이름과 동일한 key의 value만 구조분해할당 가능 (다른 이름의 변수로 지정하고 싶다면 {name: newNmae}과 같이 지정 가능)




배열 구조분해할당

const children = ["철수", "영희", "훈이"]
  • 배열도 마찬가지로 구조분해할당 가능



const [child2, child2, child3] = children
  • 선언부에 대괄호를 사용하고, 각각의 선언 변수 순서에 맞게 children의 배열의 값을 가져옴
    *가져올 때 지정할 변수의 이름은 중요하지 않지만, 선언 변수의 순서대로 배열의 인덱스값에 맞게 값을 가지게 됨





graphql의 useQuery 구조분해 할당

function useQuery (qqq)  {

    //qqq API 요청하기 코드 ~~

    return {

        data: {
            fetchBoard: {

                writer: "철수"
        },

        refetch: () => {

            console.log("refetch가 실행됩니다")
        }
    }
}
  • graphql의 useQuery도 사실상 값을 return하는 함수이며, 이 또한 그 해당값을 구조분해 할당으로 가져오고 있었음




const { data, refetch } = useQuery(FETCH_BOARDS)
  • 위와 같이 필요한 값(함수)만 전체함수에서 구조분해할당으로 뽑아와서 사용





useState의 구조분해할당

function useState (초기값) {

    let state = 초기값

    const setState = (변경값) => {

        console.log(`${state}에서 ${변경값}으로 값을 변경`) // 1. state 변경
        console.log(`변경된 ${변경값}을 사용해서 컴포넌트를 리렌더링 함`) // 2. 해당 컴포넌트 리렌더링
    }

  return [state, setState]
}
  • useState 또한 명확히 말하면 함수로서, 구조분해할당으로 return되는 값을 가져오는 방식이었던 것





const [count, setCount] = useState(0)
  • 위와 같이 배열의 구조분해할당 방식을 사용해 return 값을 가져올 수 있음








Rest 파라미터


  • 특정 객체에서 지우고 싶은 데이터가 있을 때 `rest 사용



const { money, hobby, ...rest } = child
  • 위와 같이 작성하면 child 객체에서 money,hobby 키를 제외한 모든 값이 rest라는 이름의 새로운 객체에 담기게 됨
    *꼭 이름을 rest로 지정하지는 않아도 됨! (그냥 관례임)







Custom Hooks


  • 그 동안 사용해 왔던 Hook(useState, useEffect...)들은 사실 함수였음

  • Custom Hook 은 개발자가 스스로 커스텀한 Hook으로, 사용 시 해당 함수를 호출해서 사용


Custom Hooks 사용 주의사항

  • Custom Hook를 사용하면 함수 네이밍 시 앞에 use를 붙여 사용해야 함!


  • use를 붙이지 않더라도 실행은 되지만, 의도치 않은 동작이나 에러를 발생시킬 수 있고, 이로 인해 핸들링이 어려워질 수 있기에 가급적 use를 붙여서 사용!








Custom Hooks 로 컴포넌트 분리 - 예시1 - [useAuth]



// src/components/commons/hooks/useAuth.tsx
import { useRouter } from 'next/router'
import { useEffect } from 'react'

function useAuth(){
	const router = useRouter()
	// useEffect 훅스를 사용하고 있기 때문에 커스텀 훅스입니다.
	useEffect(()=>{
		if(!localStorage.getItem("accessToken"){
			alert("로그인 후 이용 가능합니다!")
			void router.push("/23-03-login-check")
		}
	},[])
}
  • useAuth 함수를 컴포넌트를 분리하여 새로운 파일로 따로 만듬








// custom-hooks-use-auth 폴더의 index.tsx
// 이 페이지는 useAuth를 실행할 페이지입니다.

import { useAuth } from "...파일 공유"

export default function CustomUseAuthPage() {
	useAuth() 
	
  return <div>프로필 페이지 입니다.</div> 
}
  • 상위 컴포넌트에서 만들어 둔 useAuth 를 import 해서 실행



    [분리 전의 방식과 결과는 똑같지만, 훨씬 더 코드를 간결화시킬 수 있음]








Custom Hooks 로 컴포넌트 분리 - 예시2 - [useMoveToPage]



// src/components/commons/hooks/useMoveToPage.tsx

import { useRouter } from "next/router";
import { useRecoilState } from "recoil";
import { visitedPageState } from "../../../commons/store";

export function useMoveToPage() {
  const router = useRouter();
  const [visitedPage, setVisitedPage] = useRecoilState(visitedPageState);

  const onClickMoveToPage = (path: string) => () => {
    setVisitedPage(path);
    void router.push(path);
  };

  return {
    visitedPage,
    onClickMoveToPage,
  };
}
  • 기존의 useMoveToPage 함수를 위와 같이 따로 컴포넌트를 분리하여 따로 파일을 만든 다음, 그 안에 또 다른 함수 onClickMoveToPage 를 만듬

  • 이후 return에 객체 형태로 onClickMoveToPage 함수를 내보냄
    *visitedPage는 Recoil로 전역에 저장하여 방문한 페이지를 활용할 필요가 있을 때 사용하기 위해 객체 안에 담아서 함께 return






// custom-hooks-use-move-to-page 폴더의 index.tsx
import { useMoveToPage } from "커스텀 훅의 파일경로 ";

export default function CustomHooksUseMoveToPage() {
	// 커스텀 훅으로 분리한 라우터 사용 -> 리턴을 객체로했기때문에 객체로 받아오는 것 입니다.
  const { onClickMoveToPage } = useMoveToPage();

  return (
    <>
      <button onClick={onClickMoveToPage("/boards")}>게시판으로 이동</button>
      <button onClick={onClickMoveToPage("/markets")}>마켓으로 이동</button>
      <button onClick={onClickMoveToPage("/mypage")}>마이페이지로 이동</button>
    </>
  );
}
  • 상위 컴포넌트에서 import로 만들어 둔 useMoveToPage 를 불러오고 이 함수를 실행했을 때 retrun되는 객체의 키들 중 onClickMoveToPage 함수를 구조분해할당으로 꺼내옴

  • 이후 onClickMoveToPage 함수 안에 인자로 각 주소 경로를 넣어주면, 해당 함수안의 로직이 실행되어 routing 됨



    [컴포넌트 분리 전과 결과는 똑같으나 custom을 통해 코드의 간결화 가능해짐]









profile
막 발걸음을 뗀 신입

0개의 댓글