function 안에서 function으로 return 하는 함수
function aaa(){
const myAaa = "111"
return function bbb(){
const myBbb = "222"
}
}
myAaa: 매개변수
지역함수: 함수 내부에서 선언된 변수
aaa()
//실행결과
f bbb(){
const myBbb = "222"
}
(aaa())()
//실행결과
111
내부에 있는 함수(bbb
)가 외부에 있는 함수(aaa
)에 있는 지역변수에 접근할 수있다
=> 이 개념을 사용해서 HOC를 만든다
사용자 서버 안에서 로그인한 유저 / 로그인 안한 유저 로 권한을 구분
권한을 구분하는 방법으로 useEffect
에서 accessToken
이 없으면 "/login"
화면으로 페이지를 이동킨다.
export default function QuizLoginSuccessPage() {
const router = useRouter();
const { data } = useQuery(FETCH_USER_LOGGED_IN);
const { userInfo, setUserInfo, accessToken } = useContext(GlobalContext);
useEffect(() => {
if (userInfo.email) return;
if (!accessToken) {
router.push("/quiz/login");
alert("로그인을 먼저 해주세요");
}
setUserInfo({
name: data?.fetchUserLoggedIn.name,
email: data?.fetchUserLoggedIn.email,
picture: data?.fetchUserLoggedIn.picture,
});
}, []);
return (
<>
<div>로그인에 성공하셨습니다!</div>
{data?.fetchUserLoggedIn.name}님 환영합니다~
</>
);
}
권한분기를 하려면 로그인 권한을 부여하려는 페이지에 모두 위의 로직을 입력해야하는 번거로움이 있다.
따라서, 이 문제를 해결하기 위해서 HOC를 사용한다.
with
를 붙여준다. // 클로저 개념
// 외부 함수에서 받은 Component라는 변수는 내부 함수에서 사용
const withAuth = (Component) => (props) => {
const router = useRouter();
const { accessToken } = useContext(GlobalContext);
// 토큰체크
useEffect(() => {
if (!accessToken) router.push("/login");
}, []);
if (!accessToken) return <></>;
return <Component {...props} />;
};
export default withAuth;
const UserPage = (props) => {
return <div>회원 페이지입니다.</div>;
};
export default withAuth(UserPage);
- event.target.id 를 사용하지 않아 코드가 간략해진다.
- material-ui, ant-design 등의 컴포넌트를 이용하면 id 값이 날라가는 현상을 막을 수 있다.
- id는 전체 태그에서 고유해야하기 때문에, id가 남용되면 대규모 서비스에서 문제가 야기될 수 있지만 이를 방지할 수 있다.(id 중복..)
// 기존 방법
export default function Aaa(){
const onClickButton = (event) => {
console.log(event.target.id)
}
return <button id={123} onClick={onClickButton}>클릭</button>
}
// HOF 적용
export default function Bbb(){
const onClickButton = (id) => (event) => {
console.log(id)
}
return <button onClick={onClickButton(123)}>클릭</button>
}
Component
형태, HOF는 Function
형태의 차이가 있다.
Component
형태:JSX(React HTML)
를return
한다
Function
형태:JSX
를return
안한다.
withAuth
생성import { useRouter } from "next/router";
import { useEffect } from "react";
export const withAuth = (Component) => (props) => {
const router = useRouter();
useEffect(() => {
const accessTokenItem = window.localStorage.getItem("accessToken");
console.log("withAuth", accessTokenItem);
if (!accessTokenItem) {
alert("로그인을 먼저 해주세요");
router.push("./login");
}
}, []);
return <Component {...props} />;
};
import { gql, useQuery } from "@apollo/client";
import { withAuth } from "../../../src/components/commons/hocs/withAuth";
const LogInfoPage = () => {
const { data } = useQuery(FETCH_USER_LOGGED_IN);
return <div>로그인한 유저 정보 페이지</div>
};
export default withAuth(LogInfoPage);
withAuth
가 실행되고 LogInfoPage
가 실행되어 로그인 상태인 유저만 페이지에 들어갈 수 있다.