상세 컨텐츠

본문 제목

Blog App 2 GoogleAuth

React

by nata_developer 2020. 8. 20. 14:03

본문

0.앱 구조

blog-app

  • api

    • db.json

  • client

    • public

      • index.html

      • modal.html

    • src

      • actions

        • index.js

        • types.js

      • apis

        • streams.js

      • components

        • StreamCreate.js

        • StreamDelete.js

        • StreamEdit.js

        • StreamForm.js

        • StreamList.js

      • App.js

      • GoogleAuth.js

      • Header.js

      • Modal.js

    • reducers

      • authReducer.js

      • index.js

      • streamReducer.js

    • history.js

    • index.js

1.src/GoogleAuth.js

 

import React from 'react';
import { connect } from 'react-redux';
import { signIn, signOut } from '../actions';

class GoogleAuth extends React.Component {
  componentDidMount() {
    window.gapi.load('client:auth2', () => {
      window.gapi.client
        .init({
          clientId:
            '797401886567-9cumct9mrt3v2va409rasa7fa6fq02hh.apps.googleusercontent.com',
          scope: 'email'
        })
        .then(() => {
          this.auth = window.gapi.auth2.getAuthInstance();

          this.onAuthChange(this.auth.isSignedIn.get());
          this.auth.isSignedIn.listen(this.onAuthChange);
        });
    });
  }

  onAuthChange = isSignedIn => {
    if (isSignedIn) {
      this.props.signIn(this.auth.currentUser.get().getId());
    } else {
      this.props.signOut();
    }
  };

  onSignInClick = () => {
    this.auth.signIn();
  };

  onSignOutClick = () => {
    this.auth.signOut();
  };

  renderAuthButton() {
    if (this.props.isSignedIn === null) {
      return null;
    } else if (this.props.isSignedIn) {
      return (
        <button onClick={this.onSignOutClick} className="ui red google button">
          <i className="google icon" />
          Sign Out
        </button>
      );
    } else {
      return (
        <button onClick={this.onSignInClick} className="ui red google button">
          <i className="google icon" />
          Sign In with Google
        </button>
      );
    }
  }

  render() {
    return <div>{this.renderAuthButton()}</div>;
  }
}

const mapStateToProps = state => {
  return { isSignedIn: state.auth.isSignedIn };
};

export default connect(
  mapStateToProps,
  { signIn, signOut }
)(GoogleAuth);

Store에서 데이터 가져오기, signIn, signOut 액션 가져오기

export default connect(   mapStateToProps,   { signIn, signOut } )(GoogleAuth);

 

props로 signIn, signOut 액션 호출하기

  onAuthChange = isSignedIn => {

    if (isSignedIn) {

      this.props.signIn(this.auth.currentUser.get().getId());

    } else {

      this.props.signOut();

    }

};

 

props로 Store의 데이터 가져오기

 renderAuthButton() {
    if (this.props.isSignedIn === null) {
      return null;
    } else if (this.props.isSignedIn) {
      return (
        <button onClick={this.onSignOutClick} className="ui red google button">
          <i className="google icon" />
          Sign Out
        </button>
      );
    } else {
      return (
        <button onClick={this.onSignInClick} className="ui red google button">
          <i className="google icon" />
          Sign In with Google
        </button>
      );
    }
  }

 

2.actions/types

export const SIGN_IN = "SIGN_IN";
export const SIGN_OUT = "SIGN_OUT";
export const CREATE_STREAM = 'CREATE_STREAM';
export const FETCH_STREAMS = 'FETCH_STREAMS';
export const FETCH_STREAM = 'FETCH_STREAM';
export const DELETE_STREAM = 'DELETE_STREAM';
export const EDIT_STREAM = 'EDIT_STREAM';

타이핑 실수하지 않도록 쓰고자 하는 액션 이름을 상수 값으로 지정해둔다.

3.actions/index.js

import {
  SIGN_IN,
  SIGN_OUT,
} from "./types";


export const signIn = (userId) => {
  return {
    type: SIGN_IN,
    payload: userId,
  };
};

export const signOut = () => {
  return {
    type: SIGN_OUT,
  };
};

 

4.reducers/authReducer.js

import { SIGN_IN, SIGN_OUT } from "../actions/types";

const INITIAL_STATE = {
  isSignedIn: null,
  userId: null,
};

export default (state = INITIAL_STATE, action) => {
  switch (action.type) {
    case SIGN_IN:
      return { ...state, isSignedIn: true, userId: action.payload };
    case SIGN_OUT:
      return { ...state, isSignedIn: false, userId: null };
    default:
      return state;
  }
};

리듀서는 파라미터를 두 개를 받는다.
첫번째 파라미터는 현재상태이고, 두번째 파라미터는 액션 객체이다.

5.reducers/index.js

import { combineReducers } from 'redux';
import authReducer from './authReducer';

export default combineReducers({
    auth: authReducer,
})

리듀서들을 한 군데에 모아 Store에 전달한다.

'React' 카테고리의 다른 글

redux-form  (0) 2020.08.20
Blog App 4 StreamCreate  (0) 2020.08.20
react-router-dom  (0) 2020.08.20
Blog App 1 Scaffold  (0) 2020.08.20
Redux  (0) 2020.08.11

관련글 더보기