【實作記錄】Netflix Clone:最後整理

Live Demo
Github

簡介

最後是用戶登入的 auth 以及網頁的路徑。在用戶尚未登入前不能瀏覽 browser 頁面。

經過前面幾個 part,component 以及基本的功能都處理完畢。最後就可以收尾啦。

Custom Auth Listener Hook


use-auth-listener (hooks) >folded
1
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 >folded
1
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) >folded
1
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 後面要接 2 個括號
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 後面要接 2 個括號
to={
pathname: 'signin',
state: { from: location },
}
/>
)
}
return null
}}
/>
)
}
App.js >folded
1
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 : 最後整理

Comments