728x90
728x90

출처 : 인프런_따라하며 배우는 노드, 리액트 시리즈 — 기본 강의

 

Step 1) 시작 페이지 화면 구성

 

LandingPage.js 화면 구성하기 

div 태그 안에 style을 지정해주자.

import React, {useEffect} from 'react'
import axios from 'axios';

 function LandingPage(){//Functional Component 만들기
     
    
    useEffect(() => {
        axios.get('/api/hello')      //endpoint. getRequest를 server 즉 index.js로 보내질 것
        .then(response => {console.log(response)})   //server 에서 돌아온 response를 콘솔창에 출력해봄
    }, [])
    
    
    return(
         <div style={{
             display: 'flex', justifyContent: 'center', alignItems: 'center',
             width: '100%', height: '100vh'
         }}>
          
          <h2> 시작 페이지 </h2>
          


         </div>
     )
 }

 export default LandingPage

 

 

 

그럼 첫 시작 화면이 아래와 같이 뜬다.

 

 

 

 

Step 2) 로그인 페이지 작성

 

onChange에 함수를 지정해줌으로써 이메일이나 비밀번호를 입력할 때, 실시간으로 state가 변하게 해준다. 

 

 

//client/src/components/views/LoginPage/LoginPage.js


import React, { useState } from 'react'
import Axios from 'axios'
import {useDispatch} from 'react-redux';
import {loginUser} from '../../../_actions/user_action'

function LoginPage(props) {     //파라미터로 props 넣어줘야함! 로그인 완료된 후 처음 화면으로 돌아가게 하기 위함 

    const dispatch = useDispatch();

    const [Email, setEmail] = React.useState(" ")
    const [Password, setPassword] = React.useState(" ")

    const onEmailHandler = (event) => {
        setEmail(event.currentTarget.value)
    }
    
    const onPasswordHandler = (event) => {
        setPassword(event.currentTarget.value)
    }

    const onSubmitHandler = (event) => {
        event.preventDefault(); //리프레시 방지-> 방지해야 이 아래 라인의 코드들 실행 가능 

        // console.log('Email', Email);
        // console.log('Password', Password);


        let body={
            email: Email,
            password: Password
        }

        //디스패치로 액션 취하기
        dispatch(loginUser(body))
        .then(response => {
            if(response.payload.loginSuccess) {
                props.history.push('/')             //리액트에서 페이지 이동하기 위해서는 props.history.push() 이용.
               										// 로그인 완료된 후 처음 화면(루트 페이지-landingpage로)으로 돌악가게 하기 
            } else{
                alert(' Error')
            }
        })


        
    }

    return (
        <div style={{
            display: 'flex', justifyContent: 'center', alignItems: 'center',
            width: '100%', height: '100vh'
        }}>
            
            
            <form style={{display: 'flex', flexDirection: 'column'}}
                onSubmit={onSubmitHandler}
            >

                <label>Email</label>
                <input type="email" value={Email} onChange={onEmailHandler}/>   
                <label>Password</label>
                <input type="password" value={Password} onChange={onPasswordHandler}/>

                <br />
                <button>
                    Login
                </button>
            </form>

        </div>
    )
}

export default LoginPage

 

 

 

Step 3) Action 기능 구현 

Login버튼을 누르면 디스패치가 action을 수행할 수 있도록 기능을 구현한다. 그 기능들은 _action/user_action.js 를 새로 생성해서 아래와 같이 코드를 작성하자. 

- Server 에 보낼 때 Axios.post() 를 이용한다. 

//client/src/_actions/user_action.js

import Axios from 'axios';
import {
    LOGIN_USER
} from './types'
export function loginUser(dataTosubmit) {

    const request = Axios.post('/api/users/login', dataTosubmit)        //서버에 리퀘스트 날리고 
        .then(response => response.data)                     //받은 데이터를 request에 저장


        return {                    //Action 했으니까 이제 Reducer로 보냄
            type: LOGIN_USER,
            payload: request
        }
    

}

 

 

 

Step 4) Reducer 기능 구현 

 

이 다음은 Reducer 차례로, (previousState, action) 을 받아서 nextState를 리턴해주는 역할을 할것이다.

 

 

Action의 여러가지 type들을 쉽게 관리하기 위해 client/src/_actions/types.js파일을 새로 만들어서 아래와 같이 코드를 작성한다.

//action의 타입들만 관리하는 파일
export const LOGIN_USER = "login_user";
 

 

 

 

그리고 client/src/_reducers/user_reducer.js 파일도 아래와 같이 작성해준다.

import { LOGIN_USER } from '../_actions/types';


export default function(state={}, action){  //state 는 이전 상태 

    switch(action.type){        //Action에는 여러 타입 존재함. 이 타입에 따라 다르게 반응하도록 작성
        case LOGIN_USER:
            return {...state, loginSuccess: action.payload}       //... : spread operator은 파라미터 state를 그대로 가져온 것으로 빈 상태를 의미 
            break;

        default:
            return state;

    }

}

 

 

 

로그인 결과 화면 

 

MongoDB에 저장해놓은 데이터에 맞게 로그인 시도를 했는데 로그인에 실패했다.

 

터미널을 보니 아래와 같은 메세지가 떠서 구글링해보았다.

message: "Could not connect to any servers in your MongoDB Atlas cluster. One common reason is that you're trying to access the database from an IP that isn't whitelisted. Make sure your current IP address is on your Atlas cluster's IP whitelist:docs.atlas.mongodb.com/security-whitelist/",

 

 

아래 사이트를 참고해서 Network Access 문제를 해결했다. 처음 MongoDB에 접속했던 곳과 다른 곳에서 접속해서 IP 주소가 달라져서 접근 문제가 있는 것 같았다. 

 

stackoverflow.com/questions/62859081/error-could-not-connect-to-any-servers-in-your-mongodb-atlas-cluster

 

Error : “Could not connect to any servers in your MongoDB Atlas cluster”

i have a issue that i tried to fix it for a long time. i try to connect to mongo atlas cloud from nodejs with mongoose npm. now, its not my first time but i just can't find the answer my mongoose v...

stackoverflow.com

 

그러나 문제는 해결되지 않았고 포트번호를 이미 쓰고 있어서 오류가 난것이었다.

위와 같이 터미널에서 kill을 해주니 정상적으로 로그인이 된 것을 확인할 수 있었다.

 

 

로그인에 성공했고 시작페이지로 돌아갔다.

 

 

 

 

 

728x90

+ Recent posts