Live Demo
Github
簡介
最後是用戶登入的 auth 以及網頁的路徑。在用戶尚未登入前不能瀏覽 browser 頁面。
經過前面幾個 part,component 以及基本的功能都處理完畢。最後就可以收尾啦。
Custom Auth Listener Hook
use-auth-listener (hooks) >folded1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| import { useState, useEffect, useContext } from "react" import { FirebaseContext } from "../context/firebase"
function useAuthListener() { const [user, setUser] = useState() const { firebase } = useContext(FirebaseContext)
useEffect(() => { const listener = firebase.auth().onAuthStateChanged((authUser) => { if (authUser) { localStorage.setItem("authUser", JSON.stringify(authUser)) setUser(authUser) } else { localStorage.removeItem('authUser') setUser(null) } })
return () => listener() }, []) return { user } }
export default useAuthListener
|
App.js >folded1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| import React from 'react' import { Switch, Route } from 'react-router-dom' import * as ROUTES from './constants/routes'; import { Home, Signin, Signup, Browse } from "./pages" import { useAuthListener } from "./hooks"
function App() { const { user } = useAuthListener()
return ( <Switch> <Route path={ROUTES.SIGN_IN}> <Signin /> </Route>
<Route path={ROUTES.SIGN_UP}> <Signup /> </Route>
<Route path={ROUTES.BROWSE}> <Browse /> </Route> <Route path={ROUTES.HOME}> <Home /> </Route> </Switch> ); }
export default App;
|
Modifying Our App Routes to Be Protected
確保用戶在登陸之後才能瀏覽頁面,如果直接跳到 browse 頁面,會將用戶導回 sign in page.
routes.js (helpers) >folded1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| import React from 'react'; import { Route, Redirect } from 'react-router-dom';
export function IsUserRedirect({ user, loggedInPath, children, ...restProps }) { return ( <Route {...restProps} render={() => { if (!user) { return children; } if (user) { return ( <Redirect to={ pathname: loggedInPath, } /> ) } return null }} /> ) }
export function ProtectedRoute({ user, children, ...restProps }) { return ( <Route {...restProps} render={({ location }) => { if (user) { return children; } if (!user) { return ( <Redirect
to={ pathname: 'signin', state: { from: location }, } /> ) } return null }} /> ) }
|
App.js >folded1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <Switch> <IsUserRedirect user={user} loggedInPath={ROUTES.BROWSE} path={ROUTES.SIGN_IN}> <Signin /> </IsUserRedirect> <IsUserRedirect user={user} loggedInPath={ROUTES.BROWSE} path={ROUTES.SIGN_UP}> <Signup /> </IsUserRedirect> <ProtectedRoute user={user} path={ROUTES.BROWSE}> <Browse /> </ProtectedRoute> <IsUserRedirect user={user} loggedInPath={ROUTES.BROWSE} path={ROUTES.HOME}> <Home /> </IsUserRedirect> </Switch>
|
參考資料
設置身份驗證狀態觀察器並獲取用戶數據
導覽頁
Netflix Clone : 主頁
Netflix Clone : 首頁
Netflix Clone : 用戶登入頁
Netflix Clone : Browser 頁
Netflix Clone : 最後整理