-
React로 블로그 만들기 #62018~2019/React.js 2018. 10. 30. 14:00
React로 블로그 만들기 #6- 로그인 구현(3) 로그인 상태 관리 및 ContextAPI -
1. 로그인 상태 관리하기
1) src/App.js
- 앞에서 소셜 로그인을 구현하여 로그인해서 정보를 받아옴.
- 로그인 상태를 관리하기 위해 logged를 state에 생성한다.
- 로그인을 하면 logged를 true로 바꿔줄 onLogin 함수와 로그아웃을 하면 logged를 false로 바꿔줄 onLogout 함수를 만든다.
import React, { Component } from 'react';import styled from 'styled-components';import Header from './Layout/Header';import Navigation from './Layout/Navigation';import Router from './Routes/Router';import Store from './Store/store';class App extends Component {constructor(props) {super(props)this.state = {logged: false,onLogin: this.onLogin,onLogout: this.onLogout}}// Login FunconLogin = () => {this.setState({logged: true});}// Logout FunconLogout = () => {this.setState({logged: false});}render() {const { logged, onLogout } = this.state;return (<Layout><Header logged={logged} onLogout={onLogout}/><Navigation /><Content><Router /></Content></Layout>);}}export default App;2) src/Layout/Header.js
- 부모컴포넌트(App)에서 받아온 logged, onLogout을 통해 로그인 전에는 '로그인/회원가입'을 로그인 후에는 '로그아웃'으로 글씨 변경
- 로그아웃일 경우 onLogout함수를 통해 logged를 다시 false로 바꿔준다.
import React, { Component } from 'react';import styled from 'styled-components';import { Link } from 'react-router-dom';class Header extends Component {render() {const { logged, onLogout } = this.props;return (<Container><Element>{logged ?<ShortCut><Link to="/" onClick={onLogout}>로그아웃</Link></ShortCut> :<ShortCut><Link to="/login">로그인/회원가입</Link></ShortCut>}<Logo><imgwidth="100%"height="100%"src="https://t1.daumcdn.net/cfile/tistory/99CD014B5BD01FA412"alt="logo"/></Logo><Search><Link to="/" style={{textDecoration: 'none', color:'#274046'}}><h1>React Blog</h1></Link></Search></Element></Container>);}}export default Header;- Header컴포넌트의 경우 부모컴포넌트가 바로 App이므로 props를 통해 value를 전달 받을 수 있다. 그러나 Login컴포넌트의 경우는 여러 번 전달 해야 함. 따라서 전역적인 상태가 필요하다.
2. ContextAPI
- 어플리케이션에서 전역으로 상태를 관리하기 위한 라이브러리
- 리액트에서 상태 관리 라이브러리에는 대표적으로 Redux가 있음. 리덕스는 상태 관리 외에도 많은 장점이 있음. 그러나 지금 블로그 앱에서 단순한 상태 관리를 위해서 리덕스를 사용하기에는 코드가 방대하지고 복잡해므로 Context API를 사용함.
- 유저가 로그인했는 지 안했는 지 전역으로 로그인 상태를 관리함
1) src/Store/store.js 생성
- context를 만들어준다
import React from 'react';const Store = React.createContext();export default Store;2) src/App.js
- 위에서 만든 스토어를 import한다.
- Store.Provider에 전역으로 관리할 state(logged, onLogin, onLogout)를 넣어준다.
import React, { Component } from 'react';import styled from 'styled-components';import Header from './Layout/Header';import Navigation from './Layout/Navigation';import Router from './Routes/Router';import Store from './Store/store';class App extends Component {constructor(props) {super(props)this.state = {logged: false,onLogin: this.onLogin,onLogout: this.onLogout}}// Login FunconLogin = () => {this.setState({logged: true});}// Logout FunconLogout = () => {this.setState({logged: false});}render() {const { logged, onLogout } = this.state;return (<Store.Provider value={this.state}><Layout><Header logged={logged} onLogout={onLogout}/><Navigation /><Content><Router /></Content></Layout></Store.Provider>);}}const Layout = styled.div`margin: 0 auto;display: flex;width: 100%;flex-flow: row wrap;`const Content = styled.div`margin: 0 auto;`export default App;
3) src/Components/LoginContainer.js 생성- Store에 저장된 value를 사용하기 위해 Store.Consumer를 받을 컨테이너 컴포넌트 생성
- Login 컴포넌트에 Store에 저장된 onLogin함수를 넣어준다.
import React, { Component } from 'react';import Store from '../Store/store';import Login from './Login';const LoginContainer = () => (<Store.Consumer>{store => (<Login onLogin={store.onLogin}/>)}</Store.Consumer>)export default LoginContainer;4) src/Components/Login.js
- 로그인에 성공한 경우, LoginContainer를 통해 전달받은 onLogin함수를 실행한다. => this.props.onLogin();
- 또 홈 화면으로 이동하기 위해 withRouter를 이용하여 Login을 감싸준다. => this.props.history.push('/');
import React, { Component } from 'react';import { GoogleLogin } from 'react-google-login';import KakaoLogin from 'react-kakao-login';import styled from 'styled-components';import { withRouter } from "react-router-dom";class Login extends Component {constructor(props) {super(props);this.state = {id: '',name: '',provider: '',}}// Google LoginresponseGoogle = (res) => {this.setState({id: res.googleId,name: res.profileObj.name,provider: 'google'});this.props.onLogin();this.props.history.push('/');}// Kakao LoginresponseKakao = (res) => {this.setState({id: res.profile.id,name: res.profile.properties.nickname,provider: 'kakao'});this.props.onLogin();this.props.history.push('/');}// Login FailresponseFail = (err) => {console.error(err);}render() {return (<Container><GoogleLoginclientId={process.env.REACT_APP_Google}buttonText="Google"onSuccess={this.responseGoogle}onFailure={this.responseFail}/><KakaoButtonjsKey={process.env.REACT_APP_Kakao}buttonText="Kakao"onSuccess={this.responseKakao}onFailure={this.responseFail}getProfile="true"/></Container>);}}export default withRouter(Login);5) src/Routes/index.js
- Login컴포넌트를 LoginContainer 컴포넌트로 변경한다.
export { default as Home } from '../Components/Home';export { default as Login } from '../Components/LoginContainer';export { default as About } from '../Components/About';export { default as Board } from '../Components/Board';export { default as MyBoard } from '../Components/MyBoard';export { default as MyPage } from '../Components/MyPage';6) 결과
- logged가 false인 경우
- logged가 true인 경우
'2018~2019 > React.js' 카테고리의 다른 글
React로 블로그 만들기 #8 (2) 2018.11.04 React로 블로그 만들기 #7 (0) 2018.11.01 React로 블로그 만들기 #5 (3) 2018.10.29 React로 블로그 만들기 #4 (1) 2018.10.26 React로 블로그 만들기 #3 (0) 2018.10.26