-
Social Media 만들기 - 5) logout 기능 만들기 (Header)NODE.JS 2021. 7. 6. 12:39
header를 만들고 그 안에 logout기능을 만들어보자.
component>Header.js를 만들어주고 App.js에 넣어준다.
<div className="main"> {auth.token && <Header/>}
여기서 로그인페이지로 가도 로그인 되어있다면 페이지 이동하도록 login.js를 수정해준다.
import { useDispatch, useSelector } from 'react-redux'; import { Link , useHistory} from 'react-router-dom'; const {auth} = useSelector(state => state); const history = useHistory(); useEffect(() => { if(auth.token) history.push("/") }, [auth.token, history])
이제 헤더파일을 작성해준다.
여기서 navbar는 bootstrap에서 복사하는데,
index.html의 부트스트랩을 맞춰준다.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css"> <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.min.js"></script> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css" rel="stylesheet">
header.js
import React from 'react' import { useDispatch, useSelector } from 'react-redux'; import {Link, useLocation} from 'react-router-dom'; import { logout } from '../redux/actions/authActions'; const Header = () => { const navLinks = [ {label:'Home', icon:'home', path:'/'}, {label:'Message', icon:'near_me', path:'/message'}, {label:'Discover', icon:'explore', path:'/discover'}, {label:'Notify', icon:'favorite', path:'/notify'}, ] const {auth, theme} = useSelector(state => state) const dispatch = useDispatch() const {pathname} = useLocation() const isActive = (pn) =>{ if(pn ===pathname){ return 'active' } } return ( <nav className="navbar navbar-expand-lg navbar-light bg-light justify-content-between align-middle"> <Link to="/"> <h1 className="navbar-brand text-uppercase p-0 m-0" >Social Network</h1></Link> <button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span className="navbar-toggler-icon"></span> </button> <div className="menu" > <ul className="navbar-nav flex-row"> { navLinks.map((link, index)=>( <li className={`nav-item px-2 ${isActive(link.path)}`} key={index}> <Link className="nav-link" to={link.path}> <span className="material-icons">{link.icon}</span> </Link> </li> )) } <li className="nav-item dropdown" style={{opacity: 1}} > <span className="nav-link dropdown-toggle" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <img src={auth.user.avatar} alt="avatar" className="avatar" style={{filter: `${theme ? 'invert(1)': 'invert(0)'}`}}/> </span> <div className="dropdown-menu" aria-labelledby="navbarDropdown"> <Link className="dropdown-item" to={`/profile/${auth.user_id}`}>Profile</Link> <label className="dropdown-item" htmlFor="theme">{theme ? "Light mode":'Dark mode'}</label> <div className="dropdown-divider"></div> <Link className="dropdown-item" to="/" onClick={()=>dispatch(logout())}>Logout</Link> </div> </li> </ul> </div> </nav> ) } export default Header
index.css 에 디자인 추가
img{ object-fit: cover; } .avatar { width: 30px ; height: 30px ; border-radius: 50% ; border: 2px solid black; } /* ------AUTH--------- */ @import url("./styles/auth.css"); /* ------LOADING--------- */ @import url("./styles/loading.css"); /* ------LOADING--------- */ @import url("./styles/header.css");
logout의 기능을 위해서 action을 설정해준다.
export const logout = () =>async (dispatch) =>{ try{ localStorage.removeItem('firstLogin') await postDataAPI('logout') window.location.href="/" } catch (err) { dispatch({ type: GLOBALTYPES.ALERT, payload: { error: err.response.data.msg } }) }}
추가로 theme의 속성을 사용하기 위해서 (mode 변경)
globaltype을 추가해준다.
export const GLOBALTYPES={ AUTH:"AUTH", ALERT:"ALERT", THEME:"THEME" }
themReducer를 생성하고 추가
import {GLOBALTYPES} from '../actions/globalTypes'; const initialState = false; const themeReducer = (state=initialState, action) =>{ switch(action.type){ case GLOBALTYPES.THEME: return action.payload; default : return state; } } export default themeReducer;
index.js/reducer에 추가해준다.
import { combineReducers } from "redux"; import auth from './authReducers'; import alert from './alertReducer'; import theme from './themeReducer'; export default combineReducers({ auth, alert, theme })
추가로 아이콘의 설정을 따로 꺼내서 정의해준다.
component>Avatar.js생성
import React from 'react' import { useSelector } from 'react-redux' const Avatar = ({src}) => { const {theme} = useSelector(state => state) return ( <img src={src} alt="avatar" className="avatar" style={{filter: `${theme ? 'invert(1)': 'invert(0)'}`}}/> ) } export default Avatar
header.js에 다음과 같이 변경해준다.
import Avatar from '../components/Avatar'; <li className="nav-item dropdown" style={{opacity: 1}} > <span className="nav-link dropdown-toggle" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <Avatar src={auth.user.avatar} /> </span>
로그아웃도 잘 된다. 'NODE.JS' 카테고리의 다른 글
Social Media 만들기 - 7) userInfoProfile , edit profile 기능 만들기 (0) 2021.07.07 Social Media 만들기 - 6) search 기능 만들기 (Header) (0) 2021.07.06 Social Media 만들기 - 4) Register 기능 만들기 (0) 2021.07.06 Social Media 만들기 - 3) Redux , RefreshToken (Login 기능 만들기) (0) 2021.07.05 Social Media 만들기 - 2) Authentification 기능 만들기 (0) 2021.06.16