iT邦幫忙

2022 iThome 鐵人賽

DAY 25
0
Modern Web

MERN Stack + Tailwind CSS - React 小專案實踐計畫系列 第 25

【Day 25】註冊 / 登入 Authentication(3) - 前端功能

  • 分享至 

  • xImage
  •  

回到前端部分,在 api 中新增 loginregister

https://ithelp.ithome.com.tw/upload/images/20221009/20152502iv8DLsH1oe.png

createAsyncThunk

接著新增 accountSlice.js

  • 引入 api 中的使用loginregister ,然後使用 createAsyncThunk 來處理非同步函數

https://ithelp.ithome.com.tw/upload/images/20221009/20152502by1MO4SCeV.png

  • 定義初始值

https://ithelp.ithome.com.tw/upload/images/20221009/2015250201r0Cb4O0m.png

  • 建立 slice,除了一般的 reducer 之外,新增 extraReducers

https://ithelp.ithome.com.tw/upload/images/20221009/20152502lE2TXtTSPj.png

  • extraReducers 用來處理 createAsyncThunk 建立的非同步函數,可以分為三個階段:pending, fulfilled, rejected ,依照字面上的意思很好理解,我們可以分別定義在各自的階段需要執行什麼任務,例如 status 的狀態以及是否成功註冊或登入的 login.hasLogin 布林值判斷

https://ithelp.ithome.com.tw/upload/images/20221009/20152502N6jnXXNtyB.png

  • 最後記得要輸出~

https://ithelp.ithome.com.tw/upload/images/20221009/20152502AIwhMoFWyE.png

Login.jsRegister.js

接下來調整登入及註冊頁面的功能:

  • 引入 loginAsync ,並在 handleLogin 中搭配 dispatch 使用
  • 引入 useSelector ,取出全域變數 account.status 以及 account.user ,並使用 useEffect 來判斷 loginAsync 的執行階段
  • 引入 useNavigate ,如果登入成功的話,將畫面跳轉至首頁 → navigate('/')
import React, { useState, useEffect } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import { EnvelopeIcon, LockClosedIcon } from '@heroicons/react/24/solid';
import Header from '../components/Header';
import Footer from '../components/Footer';
import { loginAsync } from '../redux/accountSlice';

export default function Login() {
    const [email, setEmail] = useState('');
    const [password, setPassword] = useState('');

    const navigate = useNavigate();

    const loginStatus = useSelector((state) => state.account.status);
    const user = useSelector((state) => state.account.user);
    const dispatch = useDispatch();

    const handleLogin = async () => {
        dispatch(loginAsync({ email, password }));
    };

    useEffect(() => {
        if (loginStatus === 'idle' && user.name) {
            alert('登入成功!');
            navigate('/');
        }
    }, [loginStatus]);
		...
}

Register.js 也是相同的概念~

https://ithelp.ithome.com.tw/upload/images/20221009/201525023YVzmtManb.png

修改 Header.js

取得全域變數 account.login.hasLogin 以及 account.user ,並使用 hasLogin 來判斷使用者是否已登入來改變 header 的顯示 → {hasLogin ? <></> : <></>}

import { useSelector } from 'react-redux';

const { hasLogin } = useSelector((state) => state.account.login);
const { name, photo } = useSelector((state) => state.account.user);

{hasLogin ? (
    <>
        <Link
            to={'/add-post'}
            className="flex mx-5 text-white font-medium px-4 py-2 bg-yellow-700/40 hover:bg-yellow-700/70 rounded-md"
        >
            <PencilIcon className="h-6 w-6 mr-2" />
            寫點東西
        </Link>
        <Link to={'/'} className="flex mx-5 hover:text-yellow-700 align-middle">
            {photo ? (
                <img className="w-9 h-9 rounded-full" src={photo} alt="avatar" />
            ) : (
                <div className="w-9 h-9 rounded-full bg-yellow-700/70" />
            )}
            <span className="font-medium ml-4 my-auto">Hi, {name}</span>
        </Link>
    </>
) : (
    <Link
        to={'/login'}
        className="flex mx-5 text-white font-medium px-4 py-2 bg-yellow-700/40 hover:bg-yellow-700/70 rounded-md"
    >
        登入 / 註冊
    </Link>
)}

修改 AddPost.js

取得全域變數 account.user 中的 name ,然後傳給 createPost api

import { useSelector } from 'react-redux';

const author = useSelector((state) => state.account.user.name);

const handleAddPost = async () => {
    const res = await createPost({ title, author, image, content });
    console.log(res.data);
    setTitle('');
    setImage('');
    setContent('');
};

目前的畫面及功能呈現

https://ithelp.ithome.com.tw/upload/images/20221009/201525027BKnbYDuI7.png

這樣就大致完成了註冊 / 登入的功能啦~ 當然還有很多細節需要調整及修改,如果後續有機會再來調整!


上一篇
【Day 24】註冊 / 登入 Authentication(2) - 處理後端驗證
下一篇
【Day 26】搜尋功能 - MongoDB Atlas Search
系列文
MERN Stack + Tailwind CSS - React 小專案實踐計畫30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言