반응형

이전글 정보 ↓

https://myhappyman.tistory.com/302
 

서버 설정이 끝났으니 뷰를 작성하고 rest api를 통해 요청을 진행한다.
* 전부 클라이언트(react) 부분에 대한 설정이므로 모든 경로는 'client/~' 으로 시작한다.
 

🗂️ 작업 디렉토리 구조

 

⚙️ 추가 설치

추가할 라이브러리부터 설치한다.

$ cd client
$ npm install recoil
  • recoil: 전역 state 관리
     

🚀 React 설정 및 개발

전역 state 처리용

 

📄/src/atom.ts

import { atom } from "recoil";

export const loginInfo = atom({
    key: "loginInfo",
    default: "",
});

 

📄/src/index.tsx

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { RecoilRoot } from "recoil";

const root = ReactDOM.createRoot(
    document.getElementById("root") as HTMLElement
);
root.render(
    <React.StrictMode>
        <RecoilRoot>
            <App />
        </RecoilRoot>
    </React.StrictMode>
);

recoil 적용
 

📄/src/App.tsx

import React from "react";
import { useRecoilValue } from "recoil";
import { loginInfo } from "./atom";
import Login from "./components/login/login";
import MyPage from "./components/login/mypage";

function App() {
    const loginUser = useRecoilValue(loginInfo);
    return (
        <div className="App">{loginUser !== "" ? <MyPage /> : <Login />}</div>
    );
}

export default App;

loginInfo정보에 따라 로그인 페이지, 마이페이지 컴포넌트 설정
아직 MyPage에 대한 작성이 없으므로 작성을 시작한다.
 

🪄 마이페이지 작성

📄/src/components/login/mypage.tsx

import { useRecoilState } from "recoil";
import { loginInfo } from "../../atom";
import { useEffect, useState } from "react";

export default function MyPage() {
    const [loginUser, setLoginUser] = useRecoilState(loginInfo);
    const [userEmail, setUserEmail] = useState("");

    const logout = () => {
        fetch("/login/logout")
            .then((res) => res.json())
            .then((res) => {
                console.log(res);
                setLoginUser("");
            });
    };

    useEffect(() => {
        fetch("/login/getUserInfo")
            .then((res) => res.json())
            .then((res) => {
                const { user_email } = res.data;
                setUserEmail(user_email);
            });
    }, []);
    return (
        <div>
            <h2>My Page!</h2>
            <div>
                <label htmlFor="">접속한 아이디</label>
                <div>{loginUser}</div>
            </div>
            <div>
                <label htmlFor="">이메일</label>
                <div>{userEmail}</div>
            </div>
            <div>
                <button onClick={logout}>로그아웃</button>
            </div>
        </div>
    );
}

 

🔑 로그인 페이지 구현

📄/src/components/login/login.tsx

import { useState, useEffect } from "react";
import { useSetRecoilState } from "recoil";
import { loginInfo } from "../../atom";

export default function Login() {
    const [userId, setUserId] = useState("");
    const [userPw, setUserPw] = useState("");
    const setLoginInfo = useSetRecoilState(loginInfo);

    const handleInput = (e: React.ChangeEvent<HTMLInputElement>) => {
        if (e.target.name === "userId") {
            setUserId(e.target.value);
        } else if (e.target.name === "userPw") {
            setUserPw(e.target.value);
        }
    };

    const goLogin = () => {
        const data = {
            userId: userId,
            userPw: userPw,
        };
        fetch("/login/login", {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                Accept: "application / json",
            },
            body: JSON.stringify(data),
        })
            .then((res) => res.json())
            .then((data) => {
                const { msg } = data;
                if (msg === "success") {
                    setLoginInfo(userId);
                }
            })
            .catch((err) => console.log(err));
    };

    useEffect(() => {
        fetch("/login/getUserInfo")
            .then((res) => res.json())
            .then((res) => {
                const { msg, data } = res;
                if (msg === "success" && data?.user_id) {
                    setLoginInfo(data?.user_id);
                }
            });
    }, [setLoginInfo]);

    return (
        <div>
            <h2>Login Test</h2>
            <div>
                <label htmlFor="">아이디</label>
                <input
                    type="text"
                    name="userId"
                    value={userId}
                    onChange={handleInput}
                />
            </div>
            <div>
                <label htmlFor="">비밀번호</label>
                <input
                    type="password"
                    name="userPw"
                    value={userPw}
                    onChange={handleInput}
                />
            </div>
            <div>
                <button type="button" onClick={goLogin}>로그인</button>
            </div>
        </div>
    );
}
반응형