개발새발

로그인, 로그아웃 상태에 따른 화면 구현에 대한 고찰 본문

FRONT/React

로그인, 로그아웃 상태에 따른 화면 구현에 대한 고찰

칸쵸. 2024. 1. 20. 20:42
728x90

 

1. 개발환경 

React로 페이지 구현

SpringBoot로 서버 구현

 

2. 기존 코드 

import React, { useState, useEffect } from 'react';
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';
import axios from 'axios';
import User from './UserList';
import SignUp from './SignUp';
import Login from './Login';

function App() {
 
  const [userEmail, setUserEmail] = useState('');
  const [isAuthenticated, setIsAuthenticated] = useState(false);

  useEffect(() => {
    const fetchUserData = async () => {
      try {
        const res = await axios.get('http://localhost:8080/userdata', {
          withCredentials: true,
        });
        setUserEmail(res.data.userEmail);
        // setAuthentication 함수 호출
        setAuthentication(setIsAuthenticated, res.data.userEmail);
      } catch (err) {
        console.error('세션 데이터 불러오기 실패', err);
      }
    };
    fetchUserData();
  }, []);

  // setAuthentication 함수를 외부로 분리
  const setAuthentication = (setIsAuthenticated, userEmail) => {
    if (userEmail !== '') {
      setIsAuthenticated(true);
    }
  };

  return (
    <Router>
      <Link to="/">UserList</Link>
      {isAuthenticated || (
        <>
          <Link to="/signup">SignUp</Link>
          <Link to="/login">Login</Link>
        </>
      )}
      <h1>React & SpringBoot로 회원관리</h1>
      <Routes>
        <Route path="/" element={<User />} />
        {isAuthenticated || (
          <>
            <Route path="/signup" element={<SignUp />} />
            <Route path="/login" element={<Login />} />
          </>
        )}
      </Routes>
    </Router>
  );
}

export default App;

 

3. 문제점 

 

문제 1)

화면의 렌더링 이후 세션값을 받아와서, 로그인 상태라면 재렌더링이 발생한다
렌더링 이전에 세션값 유무를 판단하는 방법이 없을까?


해결:

// isAuthenticated 값이 false인 경우 아무것도 렌더링 하지 않는 if문 추가
  if (!isAuthenticated) {
    return null;
  }



문제 2)

이렇게 될 경우 세션값이 존재하는 상황에서는 의도한 화면이 구현되나,
문제는 로그아웃(세션값X) 상태에서 화면을 렌더링 할 경우 아무것도 나오지 않는 불상사가 일어난다
세션값이 없는 상태에서 렌더링 되는 화면은 어떻게 지정할 것인가...?

어쩐지 모순인 상황
1)

로그인 상태(세션값 O) -> 첫 렌더링(세션값 읽어오기 전) : 아무것도 리턴 X -> 세션값 읽어오고 재렌더링 : 로그인 상태에서 보일 요소 등장!

2)

로그아웃 상태(세션값x) -> 첫 렌더링(세션값 읽어오기 전) : 아무것도 리턴 X -> 세션값 읽어옴(여전히 값 없음) -> 아무것도 안보임 
-> 아니 그럼 로그인은 어케함?!


해결:

드디어 해결했다!!!! if문과 함께 삼항연산자를 사용해서 해결 완료 ㅠㅠ

 

3. 최종 코드 

import React, { useState, useEffect } from 'react';
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';
import axios from 'axios';
import User from './UserList';
import SignUp from './SignUp';
import Login from './Login';

function App() {
  const [userEmail, setUserEmail] = useState('');
  const [isAuthenticated, setIsAuthenticated] = useState(false);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    const fetchUserData = async () => {
      try {
        const res = await axios.get('http://localhost:8080/userdata', {
          withCredentials: true,
        });
        setUserEmail(res.data.userEmail);
        setAuthentication(res.data.userEmail);
      } catch (err) {
        console.error('세션 데이터 불러오기 실패', err);
      } finally {
        setIsLoading(false);
      }
    };
    fetchUserData();
  }, []);

  const setAuthentication = (userEmail) => {
    if (userEmail !== '') {
      setIsAuthenticated(true);
    }
  };

  // 초기 로딩 중에는 아무것도 반환X
  if (isLoading) {
    return null;
  }

  // 초기 렌더링 시에는 세션값이 있는지 여부에 따라 적절한 화면을 반환
  return (
    <Router>
      <Link to="/">Main</Link>
      {isAuthenticated ? (
        null
      ) : <>
      <Link to="/signup">SignUp</Link>
      <Link to="/login">Login</Link>
    </>}
      <h1>React & SpringBoot로 회원관리</h1>
      <Routes>
        <Route path="/" element={<User />} />
        {!isAuthenticated && (
          <>
            <Route path="/signup" element={<SignUp />} />
            <Route path="/login" element={<Login />} />
          </>
        )}
      </Routes>
    </Router>
  );
}

export default App;

 

 

 

~ 요약 ~

1. isLoading : 초기 로딩 중에는 null 반환해서 아무것도 안보이게 하기

2. 그리고 세션값을 읽어와서 세션값 유무에 따라 다른 화면이 나타나게 하기

3. 삼항 연산자를 통해 isAuthenticated 상태에 따라 다른 인터페이스를 렌더링