[JavaScript] 선언적 함수(함수 선언문), 익명함수(함수 표현식)

hoc 적용 중에 AuthenticationCheck 이름을 가진 함수에서 무한루프가 발생하는 문제가 발생했다. 단순히 로그인을 판단하는 localstorage에 저장되는 시점과 읽어오는 시점에 충돌이 일어난 문제인줄 알았다. 그래서 코드를 변경해보았지만 쉽게 해결할 수 없었고 기존에 사용했던 코드만 보는 것이 아니라 다른 사람이 사용한 hoc를 찾아보다가 hint를 발견 할 수 있었다.

기존에 시도했던 hoc코드

import React, { useEffect } from 'react';
import { useSelector } from 'react-redux';

export default function (SpecificComponent, option) {
  function AuthenticationCheck(props) {
    let user = useSelector(state => state.user);
    let isAuth = localStorage.getItem('token');

    //Not Loggined in Status
    if (isAuth === null) {
      if (option) {
        props.history.push('/login');
      }
      //Loggined in Status
    } else {
      if (option === false) {
        props.history.push('/');
      }
    }

    return <SpecificComponent {...props} user={user} />;
  }
  return AuthenticationCheck;
}
  • 문제가 발생했던 부분은 아래 부분이었다.
function AuthenticationCheck(props)
  • 다른 사람의 hoc코드에서 => 를 사용한 모습을 보고 아차 했다. 이후 적용한 결과 무한루프에서 빠져나올수 있었다.
  • 그럼 여기서 function=> 함수의 차이점에 대해서 궁금증이 생겼다.

선언적 함수 & 익명 함수?

선언적 함수 (함수 선언문)

  • 함수 선언문은 함수 이름을 생략할 수 없다.
fucntion add(x,y){
	return x + y 
}

익명함수

const add = function(x,y){
	return x + y
}

비교

add(1,2);
function add(first, second) {
  return first + second;
}

선언적 함수는 글로벌(전역)에 등록되어 나중에 선언하는 것이 가능하다.

add(1,2);
var add = function(first, second) {
  return first + second;
}
// Uncaught TypeError: add is not a function

익명의 함수는 다른 코드와 같이 런타임 순서대로 실행되기 때문에 TypeError 가 발생하게 된다

  • 함수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징을 함수 호이스팅(function hoisting)이라 한다.
  • var 키워드 사용과 함수 선언문은 둘다 JS 엔진에 의해 먼저 실행되어 식별자를 생성한다는 점에서 동일하지만 var 키워드로 선언된 변수는 undefined로 초기화되고, 함수 선언문을 통해 생성된 식별자는 함수 객체 로 초기화 된다. 그래서 선언문으로 정의한 함수를 선언문 이전에 호출하면 함수 호이스팅에 의해 호출이 가능하다
  • 즉, 함수 표현식으로 함수를 정의하면 함수 호이스팅이 발생하는 것이 아니라 변수 호이스팅이 발생한다. 함수 표현식으로 정의한 함수는 반드시 함수 표현식 이후에 참조 또는 호출해야 한다.

다시 생각해 보면 hoc를 적용한 Auth()가 시작과 동시에 호출이 가능하다,

로그인 → 토큰 locastorage 저장 → Auth() → localstorage 토큰을 통해 로그인 유뮤 확인 → 유뮤에 따른 로직 → 권한 관리 완료

방식의 로직을 원했었는데

여기서 Auth()를 사용함로써 토큰을 가져오는 부분에서 무한 루프가 발생하였다. => 를 활용하여 함수 표현식으로 변경하였고 Auth를 호출 했을 때 해당 함수가 작동하기 때문에 무한 루프에서 빠져나올 수 있었다.

문제를 해결한 hoc 코드

import React, { useEffect } from 'react';
import { useSelector } from 'react-redux';
/* 
     예)  option: null -> 누구나 출입이 가능한 페이지
                 true -> 로그인한 유저만 출입이 가능한 페이지
                 false -> 로그인한 유저가 account 페이지 가려고 하면 막아준다
  */
export default function (SpecificComponent, option) {
    const AuthenticationCheck = props => {
        let user = useSelector(state => state.user);
        let isAuth = localStorage.getItem('token');

        //Not Loggined in Status
        if (isAuth === null) {
            if (option) {
                props.history.push('/account');
            }
            //Loggined in Status
        } else {
            if (option === false) {
                props.history.push('/');
            }
        }

        return <SpecificComponent {...props} user={user} />;
    };
    return AuthenticationCheck;
}

좋은 웹페이지 즐겨찾기