개발공부

토이 프로젝트 - A - JAE GAG 페이지 구성 - 메인 페이지, 헤더

카로루딘 2023. 8. 27. 23:52

가장 기본이 되는 페이지

사용 기술 - react-query, styled-components, react, type-script

 

깃허브 페이지 - https://github.com/Nidurolak/asd/blob/master/src/pages/Main.tsx

 

이 페이지에서는 기본적인 방식으로만 제작되어 크게 리뷰할 부분이 있지는 않다. 역할은 다른 페이지로의 이동을 관리하는 것으로 끝이며, 스크립트 구조는 위 링크를 따라가면 볼 수 있다. 이 페이지 자체는 유니크한 역할이 부여되지 않고 간단한 네비게이트와 api 연결 하나만 제공되어 있다.

 
 const [contentlist, setContentlist] = useState<any>([])
 const { isLoading } = useQuery(["getMain",], getMainGag,{onSuccess:({ data })=>{setContentlist(data.data)}})
 

리액트 쿼리를 이용한 간단한 Get 연결이다. api 요청으로 무작위 gag와 그 ID 넘버를 받아와 할당한다.

 

 
    return (<>
      <Maincontainer>
        <MainTitleContainer>
        <h1>ㅇㅈ개그</h1>
        <h2>당신의 개그는 아재? 인정?</h2>
        </MainTitleContainer>
        <SubTitleContainer>
        <h3>{contentlist.title}</h3>
        <h4 onClick={()=>navigate(`/GagDetail/?id=${contentlist.gagId}`)}>대답할 자신있다면 클릭!</h4>
        </SubTitleContainer>
        <ButtonContainer>
        <MainButton name = {"개그 맞춰보기"} link = {`/GagDetail/?id=${contentlist.anotherGagId}`}></MainButton>
        <MainButton name = {"개그 올려보기"} link = {""}></MainButton>
        <MainButton name = {"개그 전부보기"} link = {"/GagList"}></MainButton>
        </ButtonContainer>
      </Maincontainer>
      </>);}
 

텍스트 CSS는 스타일드 컴포넌트 지정할 때 같이 해주었으며 MainButton은 컴포넌트로 분리하였다. 


function MainButton (props: MainButtonProps){
    const {name, link} = props;
    const navigate = useNavigate();
    const LoginState = useSetRecoilState(loginState);
    const GagModalState = useSetRecoilState(gagModalState)
 
    const ButtonActive = () =>{
        if(link != ""){
            navigate(link)
        }
        else{
            getLocalStorage("username") == null || undefined ?LoginState(true) :GagModalState(true)
        }
    }

    return(<ButtonStyle onClick={() =>ButtonActive()}>
        <p>{name}</p>
    </ButtonStyle>)
}

MainButton의 스크립트 기본 구조이다. 역시 유니크한 기능은 없으며 네비게이션 역할을 맡고 있다. 이걸 따로 구분해 놓은 이유는 타입 스크립트 연습 중 props로 값을 어떻게 넘기는지 테스트 해보기 위한 것이었다. "props: MainButtonPorps"는 따로 파일을 분리해 놓은 types 스크립트에 구분해 놓았으며 해당 타입 구조는

 
export interface MainButtonProps {
  name : string;
  link : string;
}

로 되어 있다.

-헤더-

헤더는 단순히 "항상 노출되는 컴포넌트"로서의 기능보다는 좀 더 딥한 기능, 예컨데 쿠키 관리나 로컬 스토리지 관리 등을 맡길 수 있다.

 
function Header (){

    const navigate = useNavigate();
    const Loginstate = useSetRecoilState(loginState)
    const nickname = getLocalStorage("username")
    const LoginState = useRecoilValue(loginState);
    const GagModalState = useRecoilValue(gagModalState);

    useEffect(()=>{
        if(getCookie("token") == null || undefined && nickname !== null){
            removeLocalStorage("username");
        }
        if(getLocalStorage("solvedList") == null || undefined){
          setLocalStorage("solvedList", [])
        }
       
    }, [getCookie("token")])
    const onLogout = () => {
        removeCookie("token");
        removeLocalStorage("username");
        navigate("/");
        window.location.reload();
      };
   

    return(<>
      <HeaderBox>
      <h3 onClick={() => {navigate("/");}}>ㅇㅈ개그</h3>
      {nickname !== null
      ? <NameBox>
        <h5 onClick={()=>{navigate("/Profile")}}>{nickname}님 환영합니다!</h5>
        <h5 onClick={() => onLogout()}>로그아웃</h5>
        </NameBox>
      : <h4 onClick={()=> Loginstate(true)}>로그인/회원가입</h4>}
      </HeaderBox>
      {GagModalState === true && <GagModal/>}
      {LoginState === true && <LoginModal />}
    </>)
}

useEffect로 쿠키의 만료 여부를 체크하여 만료되었는데 회원 전용 기능을 사용하려 한다면 메인 페이지로 넘어가며 동시에 로그아웃 처리를 위해 로컬 스토리지를 비우도록 설정해 놓았다. 이를 통해 따로 로그인 체크를 위한 스크립트를 만들어 넣지 않아도 항상 노출되는 헤더에서 겸사겸사 철리할 수 있게 해놓았다. 따로 사용을 위해 분리한 컴포넌트는 없다.