hoc 적용 중에 AuthenticationCheck 이름을 가진 함수에서 무한루프가 발생하는 문제가 발생했다. 단순히 로그인을 판단하는 localstorage에 저장되는 시점과 읽어오는 시점에 충돌이 일어난 문제인줄 알았다. 그래서 코드를 변경해보았지만 쉽게 해결할 수 없었고 기존에 사용했던 코드만 보는 것이 아니라 다른 사람이 사용한 hoc를 찾아보다가 hint를 발견 할 수 있었다.
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)
=>
를 사용한 모습을 보고 아차 했다. 이후 적용한 결과 무한루프에서 빠져나올수 있었다.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 가 발생하게 된다
undefined
로 초기화되고, 함수 선언문을 통해 생성된 식별자는 함수 객체
로 초기화 된다. 그래서 선언문으로 정의한 함수를 선언문 이전에 호출하면 함수 호이스팅에 의해 호출이 가능하다다시 생각해 보면 hoc를 적용한 Auth
()가 시작과 동시에 호출이 가능하다,
로그인 → 토큰 locastorage 저장 → Auth() → localstorage 토큰을 통해 로그인 유뮤 확인 → 유뮤에 따른 로직 → 권한 관리 완료
방식의 로직을 원했었는데
여기서 Auth()를 사용함로써 토큰을 가져오는 부분에서 무한 루프가 발생하였다. =>
를 활용하여 함수 표현식으로 변경하였고 Auth를 호출 했을 때 해당 함수가 작동하기 때문에 무한 루프에서 빠져나올 수 있었다.
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;
}