로그아웃 서비스
로그인 기능은 완료되었는데 로그아웃 기능이 현재 없습니다.
로그아웃 기능은 어떻게 만들까요?
우리는 로그인을 위해 엑세스 토큰을 로컬 스토리지에 추가했습니다.
로그아웃은 이를 반대로 해주면 됩니다.

로컬 스토리지에 존재하는 액세스 토큰을 제거하고 로그인 페이지로 리디렉트 하는것입니다.
ApiService.js
비록 백엔드 서버에 요청하는 로직은 아니지만
코드관리를 위해 로컬 스토리지에 관련된 모든 것은 ApiService에 작성햬왔고 계속하겠습니다.
signout 함수를 만들어보겠습니다.
export function signout(){
localStorage.setItem(ACCESS_TOKEN, null);
window.location.href = "/login";
}
그러나 아직 로그아웃 버튼이없습니다.
우리가 원하는 것은 보통 웹사이트처럼 상단에 리스트가 나온다던가 로그인, 로그아웃 등이있는
형태를 네비게이션바라고 합니다.
이것을 App컴포넌트에 추가하여 줍시다.!!
import React from 'react';
import TodoList from './TodoList';
import AddTodo from './AddTodo';
import { Paper, List, Container,Grid,Button,AppBar,Toolbar,Typography } from "@material-ui/core";
import '../../css/App.css';
import { call,signout } from '../service/ApiService';
var todoURL = "/todo";
class App extends React.Component{
constructor(props){
super(props);
this.state={
items : [],
};
}
componentDidMount() {
call(todoURL, "GET", null).then((response) =>
this.setState({ items: response.data })
);
}
add = (item) => {
call(todoURL, "POST", item).then((response) =>
this.setState({ items: response.data })
);
};
delete = (item) => {
call(todoURL, "DELETE", item).then((response) =>
this.setState({ items: response.data })
);
};
update = (item) => {
call(todoURL, "PUT", item).then((response) =>
this.setState({ items: response.data })
);
};
render() {
var todoItems = this.state.items.length > 0 && (
<Paper style={{ margin: 16 }}>
<List>
{this.state.items.map((item, idx) => (
<TodoList
item={item}
key={item.id}
delete={this.delete}
update={this.update}
/>
))}
</List>
</Paper>
);
//navigationBar 추가
var navigationBar = (
<AppBar position='static'>
<Toolbar>
<Grid justify="space-between" container>
<Grid item>
<Typography variant="h6">오늘의 할일 :: TO DO</Typography>
</Grid>
<Grid>
<Button color="inherit" onClick={signout}>
로그아웃
</Button>
</Grid>
</Grid>
</Toolbar>
</AppBar>
);
//props로 넘겨주기
return (
<div className="App">
{navigationBar}{/*내비게이션 바 렌더링*/}
<Container maxWidth="md">
<AddTodo add={this.add} />
<div className="TodoList">{todoItems}</div>
</Container>
</div>
);
}
}
export default App;
이때 주목해야할 점이있습니다. 버튼의 onClick에 signout함수를 연결해 준것에 주목해주세요,
이제 로그아웃을 테스팅을 할 수 있습니다.
로그아웃을 버튼을 클릭하면 로그인 페이지로 돌아가는것을 할 수 있습니다.
UI 글리치 해결
눈치챘지만 로그인 하지 않은 상태에서 http://localhost:3000 에 접속하면 잠깐 Todo
리스트 페이지가 아주잠깐 보이다가 로그인 화면으로 넘어갑니다.

Todo 리스트페이지에 접속한 후 로그인 페이지로 라우팅하기 까지 시간이 걸리기 때문입니다.
이 시간은 백엔드 서버에 Todo를 요청하고 결과를 받아 확인하는데 걸리는 시간입니다.
물론 메인 페이지에 아무 리스트도 보이지 않으나, 사용자는 로그아웃 상태에서 아무것도
할 수 없지만 UI가 이렇게 오락가락 하는 것은 사용성 측면에서 좋지않습니다.
이를 방지하려면 백엔드에서 Todo 리스트를 받아오기 전까지는
로딩중 이라는 메시지를 띄우도록 합시다.
App.js에 로딩중 로직을 추가해 줍시다.
//기존 코드들 //
class App extends React.Component{
constructor(props){
super(props);
this.state={
items : [],
/*(로딩중이라는 상태를 표현할 변수를 생성자에 상태 변수를 추가합니다.)*/
loading: true,
};
}
//수정된 부분
componentDidMount() {
/*componetDidMount에서 Todo리스트를 가져오는 Get요청이 성공적으로 리턴하는 경우 loading을 false로 고칩니다.
더 이상 로딩중이 아니라는 뜻이 됩니다.*/
call(todoURL, "GET", null).then((response) =>
this.setState({ items: response.data, loading: false })
);
}
/*
* 기존코드들 쭈욱있고~
*/
//수정된 부분
var todoListPage=(
<div>
{navigationBar}{/*내비게이션 바 렌더링*/}
<Container maxWidth="md">
<AddTodo add={this.add}/>
<div className='TodoList'>{todoItems}</div>
</Container>
</div>
);
/* 로딩중일 때 렌더링 할 부분 */
var loadingPage = <h1> 로딩중.. </h1>;
var content = loadingPage;
if (!this.state.loading) {
/* 로딩중이 아니면 todoListPage를 선택*/
content = todoListPage;
}
/* 선택한 content 렌더링 */
return <div className="App">{content}</div>;
}
}
추가해주었습니다.
이제 로딩중이라는 화면이 나옵니다 .그러나 너무 빨라서 잘안보입니다.
개발자모드에서 디버깅을 통해 보여드리겠습니다!!
이렇게 나옵니다. 지금포스팅은 디테일한 관점에서 들어갔습니다.
다음 포스팅은 계정생성을 하는 페이지를 구현해보도록 해보겠습니다.!!!
'Spring boot 프로젝트 기록 > 2. 프론트엔드 개발' 카테고리의 다른 글
계정 생성 페이지구현 (0) | 2021.12.16 |
---|---|
액세스 토큰 저장 (0) | 2021.12.15 |
로그인 페이지 (0) | 2021.12.15 |
로그인 컴포넌트 (0) | 2021.12.14 |
서비스통합(백엔드와 프론트엔드 통합하기) (0) | 2021.12.01 |
댓글