プロジェクト1-登録、ログアウト、検証


すべての項目1-登録、ログアウト、検証


📕会員収入


今回は会員登録ページを作りましょう.
前に作成したログインページと同じ場所がたくさんあるので、コードをすべてコピーします.
2つの入力バーを作成するには、名前、Eメール、パスワード、パスワードの確認バーが必要です.
同様にstateを2つ追加する必要があります
さらにハンドルを2つ作ります.
  const  [Email, setEmail] = useState("")
  const  [Name, setName] = useState("")
  const  [Password, setPassword] = useState("")
  const  [ConfirmPassword, ConfirmsetPassword] = useState("")

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

  const onNameHandler = (event) => {
    setName(event.currentTarget.value)
  }

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

  const onConfirmPasswordHandler = (event) => {
    setConfirmPassword(event.currentTarget.value)
  }

        <label>Email</label>
        <input type="email" value={Email} onChange={onEmailHandler} />
        
        <label>Name</label>
        <input type="text" value={Name} onChange={onNameHandler} />

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

        <label>Confirm Password</label>
        <input type="password" value={ConfirmPassword} onChange={onConfirmPasswordHandler} />
私はこのように追加しました
完全なコードは次のとおりです.
import React, { useState } from 'react'
import { useDispatch } from 'react-redux'
import { useNavigate } from 'react-router-dom'
import { loginUser } from '../../../_actions/user_action'


function RegisterPage(props) {
  const navigate = useNavigate()
  const dispatch = useDispatch()
  const  [Email, setEmail] = useState("")
  const  [Name, setName] = useState("")
  const  [Password, setPassword] = useState("")
  const  [ConfirmPassword, setConfirmPassword] = useState("")

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

  const onNameHandler = (event) => {
    setName(event.currentTarget.value)
  }

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

  const onConfirmPasswordHandler = (event) => {
    setConfirmPassword(event.currentTarget.value)
  }

  const onSubmitHandler = (event) => {
    event.preventDefault();
    
    let body = {
      email: Email,
      password: Password
    }

    dispatch(loginUser(body))
      .then(response => {
        if (response.payload.loginSuccess) {
          navigate('/')
        } 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>Name</label>
        <input type="text" value={Name} onChange={onNameHandler} />

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

        <label>Confirm Password</label>
        <input type="password" value={ConfirmPassword} onChange={onConfirmPasswordHandler} />

        <br />
        <button type="submit">
          Register
        </button>
      </form>
    </div>
  )
}

export default RegisterPage
このように会員登録ページを作成し、ページに入ると、次のように見えます.

入力バーの作成が完了し、データをサーバに転送します.
登録するときは、Dispatchで作ったものと同じでいいです.
違うことを言うなら、bodyに名前をつけなければなりません.
名前が追加されました
また、ボタンを押すように変更するには、パスワードが同じでなければなりません.
    if(Password !== ConfirmPassword){
      return alert('비밀번호가 같지않습니다.')
    }

    let body = {
      email: Email,
      name: Name,
      password: Password
    }
SubminHandlerに上記のコードを追加しました
そしてDispatchの時にLoginUserのアクションを受け取った
メンバーがアクション映画に参加するのを作成します.アクション映画の名前はsignupuserです.
user_actions.jsに追加すればいいです
ログイン動作に似ているため、コピー後にアドレスをサーバindexとする.jsで
作成したルータアドレスに変更します.
そしてサーバからデータを受信するとタイプをSIGNUPUSERに変換する.
type.jsに追加します
user_action.js
import axios from 'axios'
import { LOGIN_USER } from './types'
import { SIGNUP_USER } from './types'

export function loginUser(dataToSubmit) {
    const request = axios.post('/api/users/login', dataToSubmit)
    .then(response => response.data )

    return {
        type: LOGIN_USER,
        payload: request
    }
}

export function signupUser(dataToSubmit) {
    const request = axios.post('/api/users/signup', dataToSubmit)
    .then(response => response.data )

    return {
        type: SIGNUP_USER,
        payload: request
    }
}

types.js
export const LOGIN_USER = "login_user"
export const SIGNUP_USER = "signup_user"
そしてReducerに行ってサイン業界のプレイヤーのケースを記入する際の返信状況を記入すればいいのです
user_reducer.js
import { LOGIN_USER, SIGNUP_USER } from '../_actions/types'

export default function (state = {}, action) {
    switch(action.type) {
        case LOGIN_USER:
            return { ...state, loginSuccess: action.payload }
            break;
        case SIGNUP_USER:
            return { ...state, signupSuccess: action.payload}
            break;
        default:
            return state;
    }
}
そうすると、会員入りアクションも作られています
今では作成した動作でDispatchを行うと、結果が出ます.
onSubminHandler部のコードは以下の通りです
  const onSubmitHandler = (event) => {
    event.preventDefault();

    if(Password !== ConfirmPassword){
      return alert('비밀번호가 같지않습니다.')
    }

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

    dispatch(signupUser(body))
      .then(response => {
        if (response.payload.success) {
          navigate('/LoginPage')
        } else {
          alert('Error')
        }
    })
  }
サーバーを開き、会員登録ルートを作成し、ボタンを押します.


これでログインページに移動し、ツールを表示するとtrueに戻ることがわかります.

📘ログアウト


終了機能はかなり簡単です
別のページを作成するのではなく、ホームページにボタンを作成するだけです.
ログインページにボタンを追加し、ボタンにonclickイベントを追加し、Handlerを作成します.
ハンドルに入る内容は上と同じDispatchで、とても簡単です
user_action.jsにlogoutUser関数を追加
import { LOGOUT_USER } from './types'

export function logoutUser() {
    const request = axios.get('/api/users/logout')
    .then(response => response.data )

    return {
        type: LOGOUT_USER,
        payload: request
    }
}
types.jsにタイプを追加
export const LOGIN_USER = "login_user"
export const SIGNUP_USER = "signup_user"
export const LOGOUT_USER = "logout_user"
user_reducer.jsにケースを追加
import { LOGIN_USER, LOGOUT_USER, SIGNUP_USER } from '../_actions/types'

export default function (state = {}, action) {
    switch(action.type) {
        case LOGIN_USER:
            return { ...state, loginSuccess: action.payload }
            break;
        case SIGNUP_USER:
            return { ...state, signup: action.payload}
            break;
        case LOGOUT_USER:
            return { ...state, logoutSuccess: action.payload}
            break;
        default:
            return state;
    }
}
よし、これで終わりだ
今はDispatchだけで終わりです.
import React, { useEffect } from 'react'
import axios from 'axios'
import { useDispatch } from 'react-redux'
import { useNavigate } from 'react-router-dom'
import { logoutUser } from '../../../_actions/user_action'

function LandingPage() {
  const navigate = useNavigate()
  const dispatch = useDispatch()

  useEffect(() => {
    axios.get('/api/hello')
    .then(response => {console.log(response.data)})
  }, [])

  const onClickHandler = () => {
    dispatch(logoutUser())
      .then(response => {
        if (response.payload.LogoutSuccess) {
          navigate('/LoginPage')
        } else {
          alert('Error')
        }
    })
  }

  return (
    <div style={{display: 'flex', justifyContent: 'center', alignItems: 'center',
    width: '100%', height: '100vh'}}>
      <h2>
        시작 페이지
      </h2>

      <button  onClick={onClickHandler}>
        Logout
      </button>
    </div>
  )
}

export default LandingPage
このようにハンドルを作って、ホームページを開けて、ログインしてボタンを押します!

そのまま写真のようにログアウトして、ログインルートにやってきました!

📗検証チェック


前述したようにauth機能が必要なのは、認証されていないユーザと
プレイヤーが使えるページが違うので
たとえば、すでにログインしていますが、ログインページに入ります.
管理人しか入れないところもあるようです.
また、ログインしたユーザーのみが使用できます
機能にも制限があります
アクセス可能なページの制御にはHOCが採用されます

HOC ( Higher-Order Component )


hocは別の素子を受け入れて新しい素子に戻る関数です
私はすべての部品をhocに入れます.
また、あるユーザがページに入るとhocからサーバへ
リクエストを発行してステータスを取得
ステータスは、ユーザーがログインしているかどうか、管理者であるかどうかなどを意味します.
また、管理者ではありませんが、管理者ページにアクセスしたい場合は、
彼らが特設から入るのを止める.
authは、hocを使用するために以前に作成されたhocフォルダに移動します.jsファイルの作成
次に,サーバ側でユーザの状態を尋ね,まず受信した関数を作成する.
userEffectを使用して、auth apiをサーバに作成しました.
axiosでお願いすればいいだけ
ここで直接axiosを作るのではなく、reduceを使ってやります.
今は簡単にできるようになりました
user_action.js
import { AUTH } from './types'

export function auth() {
    const request = axios.get('/api/users/auth')
    .then(response => response.data )

    return {
        type: AUTH,
        payload: request
    }
}
types.js
export const LOGIN_USER = "login_user"
export const SIGNUP_USER = "signup_user"
export const LOGOUT_USER = "logout_user"
export const AUTH = "auth"
user_reducer.js
import { LOGIN_USER, LOGOUT_USER, SIGNUP_USER, AUTH } from '../_actions/types'

export default function (state = {}, action) {
    switch(action.type) {
        case LOGIN_USER:
            return { ...state, loginSuccess: action.payload }
            break;
        case SIGNUP_USER:
            return { ...state, signup: action.payload}
            break;
        case LOGOUT_USER:
            return { ...state, logoutSuccess: action.payload}
            break;
        case AUTH:
            return { ...state, userData: action.payload}
            break;
        default:
            return state;
    }
}
auth.js
import React, { useEffect } from "react";
import { useDispatch } from 'react-redux'
import { auth } from '../_actions/user_action'

export default function (SpecificComponent, option, adminRoute = null) {
    function AuthenticationCheck(props){
        const dispatch = useDispatch()

        useEffect(() => {
            dispatch(auth())
            .then(response => {
              console.log(response)
          })
        }, [])

        return (
            <SpecificComponent />
        )
    }

    return <AuthenticationCheck />
}
我々が構築した関数から,パラメータは素子,オプション,アミンの3種類であった.
構成部品はhocに入る構成部品で、オプションは3種類あります
null:誰でもアクセスできるページ
true:ログインユーザーのみがアクセスできるページ
false:ログインユーザーがアクセスできないページ
最後のヒントは、管理者を中に入れたい場合はtrueを追加することができます.
次はもう一つの素子をhocに入れて理解する
app.jsではroutesセクションにすべてのコンポーネントがあります
auth関数で囲むとhocに追加されます.
import { BrowserRouter as Router, Routes, Route, Link } from "react-router-dom";
import Footer from './components/views/Footer/Footer'
import LandingPage from './components/views/LandingPage/LandingPage'
import LoginPage from './components/views/LoginPage/LoginPage'
import NavBar from './components/views/NavBar/NavBar'
import RegisterPage from './components/views/RegisterPage/RegisterPage'
import Auth from './hoc/auth'

function App() {
  return (
    <Router>
      <div>
        {/* A <Switch> looks through its children <Route>s and
            renders the first one that matches the current URL. */}
        <Routes>
          <Route path="/Footer" element={<Footer />} />
          <Route path="/login" element={Auth(LoginPage, false)} />
          <Route path="/NavBar" element={<NavBar />} />
          <Route path="/signup" element={Auth(RegisterPage, false)} />
          <Route path="/" element={Auth(LandingPage, null)} />
        </Routes>
      </div>
    </Router>
  );
}

export default App;
以上のように
このようにページを開くと、ページを移動するたびにリクエストが発行されます.

初めてログインページに入るとisauthにfalseが表示されます.
ログイン後、isAuthはtrueを返します.
これらの情報とオプションを使用してブランチを行います.
auth.js
import React, { useEffect } from "react";
import { useDispatch } from 'react-redux'
import { auth } from '../_actions/user_action'
import { useNavigate } from 'react-router-dom'

export default function (SpecificComponent, option, adminRoute = null) {
    function AuthenticationCheck(props) {
        const dispatch = useDispatch()
        const navigate = useNavigate()

        useEffect(() => {
            dispatch(auth())
                .then(response => {
                    console.log(response)
                    if (!response.payload.isAuth) {
                        //로그인 하지 않은 상태 
                        if (option === true) {
                            navigate('/login')
                            alert("로그인이 필요합니다.")
                        }
                    } else {
                        //로그인 한 상태
                        if (adminRoute && !response.payload.isAdmin) {
                            navigate('/')
                            alert("권한이 없습니다.")
                        } else {
                            if(option === false){
                                navigate('/')
                                alert("이미 로그인 하였습니다.")
                            }
                        }

                    }


                })
        }, [])

        return (
            <SpecificComponent />
        )
    }

    return <AuthenticationCheck />
}
こう書いて、サイトを開いてテストします.
ログインしてからログインし、次のように表示されてログインページに移動します.