# Netflix - React、Redux (二) ### firebase > $ yarn add firebase [firebase-javascript初始設定](https://firebase.google.com/docs/web/setup?hl=zh-cn#node.js-apps) 在firebase.js加入 ```javascript= import firebase from "firebase"; const firebaseApp = firebase.initializeApp(firebaseConfig); const db = firebaseApp.firestore(); const auth = firebase.auth(); export { auth }; export default db; ``` > $ yarn start ![](https://i.imgur.com/O4htUEy.png) 他會問是否轉到port:3001,按下y 就會開啟http://localhost:3001/ ### [React Router](https://reactrouter.com/web/guides/quick-start) 如果要用 React.js 做一個 SPA,第一個想到的第三方套件應該是react-router-dom,裡面包含四個元件,BrowserRouter、Switch、Route、Link。 * BrowserRouter 是起手式元件,會包裹在 SPA 元件的外層,它使用 HTML5 History API 讓 UI 與 URL 能夠同步。 * Switch 是讓第一個符合 URL 的元件會被渲染,反之,如果沒有 Switch 則所有符合 URL 的元件都會被渲染。 * Route 是定義元件相對應的 path,當 path 符合目前的 URL 時將會被渲染。 * Link 像是 HTML 的 <a>,能夠在點擊後轉變目前的 Location。 [React-router-dom | 原理解析](https://medium.com/%E6%89%8B%E5%AF%AB%E7%AD%86%E8%A8%98/a-little-bit-of-react-router-dom-e5b809fcb127) > $ yarn add react-router-dom 在App.js裡 ```javascript= import { BrowserRouter as Router, Switch, Route } from "react-router-dom"; ``` ```javascript= return ( <div className="app"> <Router> <Switch> <Route path="/profile"> <ProfileScreen /> </Route> <Route path="/"> <HomeScreen /> </Route> </Switch> </Router> </div> ); ``` :::success react-router 跟 react-router-dom 其實是兩個不同的函式庫。實際上 react-router-dom 的核心就是 react-router ,同樣給 react native 使用的 react-router-native 其核心也是 react-router ,作者把核心功能分離出來,讓核心可以重複地被利用。 ::: 在src資料夾裡,再設一個screems資料夾,把之後需要渲染的頁面放在裡面。 ![](https://i.imgur.com/dNG6wVk.png) App.js裡給一個 const user,設置之後的用戶權限 ```javascript= function App(){ const user = null; return ( <div className="app"> <Router> {!user ? ( // 如果不是用戶就跳到登入頁面 <LoginScreen /> ) : ( <Switch> <Route path="/profile"> <ProfileScreen /> </Route> <Route path="/"> <HomeScreen /> </Route> </Switch> )} </Router> </div> ); } ``` ### <LoginScreen /> 一個小技巧是如果 input 點下去不想要有藍框框,可以在css裡加入`outline-width: 0;`。 ### <SignupScreen /> ```javascript= const emailRef = useRef(null); const passwordRef = useRef(null); ``` ```javascript= const register = (e) => { e.preventDefault(); auth .createUserWithEmailAndPassword( emailRef.current.value, passwordRef.current.value ) .then((authUser) => { console.log(authUser); }) .catch((error) => { alert(error.message); }); }; const signIn = (e) => { e.preventDefault(); auth .signInWithEmailAndPassword( emailRef.current.value, passwordRef.current.value ) .then((authUser) => { console.log(authUser); }) .catch((error) => alert(error.message)); }; ``` 在firebase裡Authentication => users 就可以看到剛剛已經註冊的Email資料 ![](https://i.imgur.com/uFzx9HB.png) :::info 在App.js裡加入 onAuthStateChanged 可以監聽登出登入狀況 ::: [參考資料:Day29 前端福音(4/4): Firebase-帳號系統&資料讀寫規則](https://ithelp.ithome.com.tw/articles/10206354) ### useSelector <font color="ea907a">useSelector</font>,這個方法允許我們直接從 Redux store 中的狀態提取數據到元件中。 透過 useSelector 可以取代掉 mapStateToProps 的使用方式 ### useDispatch <font color="ea907a">useDispatch</font>,如果我們需要發一個 action 到 Redux 的 Reducer 中更新 state,它能夠直接回傳一個 dispatch 方法,可以直接透過它觸發 Reducer傳一個 dispatch 方法,可以直接透過它觸發 Reducer,而這邊需要注意的是在文件中有提到如果我們是透過 callback 的方式來發一個 action 時,需要透過 useCallback 的方式處理,避免掉多餘的重新渲染。 所以在App.js改寫成 ```javascript= const user = useSelector(selecUser); const dispatch = useDispatch(); useEffect(() => { const unsubsctibe = auth.onAuthStateChanged((userAuth) => { if (userAuth) { // Looged in dispatch( login({ uid: userAuth.uid, email: userAuth.email, }) ); } else { // Logged out dispatch(logout()); } }); return unsubsctibe; }, [dispatch]); ``` 從features > userSlice.js拿取傳一個 dispatch,可以直接透過它觸發 Reducer。 [React Redux | 小孩子才做選擇! Hooks 和 Redux 我全都要!](https://medium.com/enjoy-life-enjoy-coding/react-redux-%E5%B0%8F%E5%AD%A9%E5%AD%90%E6%89%8D%E5%81%9A%E9%81%B8%E6%93%87-hooks-%E5%92%8C-redux-%E6%88%91%E5%85%A8%E9%83%BD%E8%A6%81-1fdd226f5d99) ### useHistory useHistory 會回傳一個物件, 裡面包含許多 navigation 方法, 例如: goBack 返回上一頁, push 到某一頁…等。 [React Router 與 Hook 的邂逅](https://tomchen60317.github.io/2020/01/22/react/React-Router-%E8%88%87-Hook-%E9%82%82%E9%80%85-2/) 在<Nav />裡的logo img加上 `onClick={() => history.push("./")}` 就可以點擊Netflix log 就可以倒回首頁。