# Project 1 Review Questions ## Javascript 1. Describe primitive data type and reference data type. What's the difference? :::success 記憶體切割成Stack和Heap,primitive data會將value存放在Stack,而reference data則將記憶體位置存在Stack中,並指向Heap中存放的Value. ::: :::info **primitive data type--基本資料型別** *boolean、number、string、null、undefined、bigint、Symbol* MDN:不是object,同時沒有methods和properties ```javascript= let obj = 3; let obj2 = obj; obj2++; console.log(obj) console.log(obj2) ``` ::: :::info **reference data type--參考資料型別** *obejct、array* ```javascript= let obj = {a:1,b:2}; let obj2 = obj; obj2.a++; console.log(obj) ``` 若執行以上操作,log出來的==obj.a==會是2,因為在複製變數時,在stack中複製的是記憶體位置,而在執行==obj2.a++== 時,會先從stack得到obj2的記憶體位置,再到Heap中更改a的值,由於obj和obj2指向同一個物件,因此執行==obj2.a++== 會同時修改obj所代表的object. ```javascript= function add(data){ data.a ++ } let obj = {a:1,b:2}; add(obj) console.log(obj) ``` ```javascript= function add(data){ data[0] ++ } let arr = [1,2,3]; add(arr) console.log(arr) ``` ```javascript= function add(data){ let d =data.slice(0,2); console.log(d) } let arr = [1,2,3]; add(arr) console.log(arr) ``` ::: 2. What's the difference between == and ===? 實務上用`===` ecma 標準(類似IFRS) :::info ==(一般相等): JavaScript 在比較之前將操作數轉換為相同的數據類型。 ===(嚴格相等) 不會進行類型轉換。如果操作數的數據類型不同,直接返回 false。 ::: 3. Describe the naming convention in JavaScript and React. How do we name different variables, functions, components and modules? How to use prefix and suffix? When to use noun and verb? When should we use plural nouns? :::info 匈牙利命名法(不要用) ### variables 1. camelCase 2. 變數名稱應該可以顧名思義、並直接描述儲存的值。 3. 變數為布林值應在前面加上 is、has 或 Should 來表示。 4. 使用大寫字母加上底線來表示常數。Snake_Case ### functions 1. camelCase 2. Use descriptive nouns and verbs as prefixes. 3. onClick 對應 hanldeClick ### components 1. Pascal case 2. 避免縮寫,使用完整單字 3. Prefix High-Order Components with “with”. ### modules 1. lower case and usually dash-separated 如果有一個名為 UserCard 的 component,則該檔案應命名為 UserCard.js ::: 4. What are truthy/falsy values? :::info truthy: That is, all values are truthy except false, 0, -0, 0n, "", null, undefined, NaN, document.all 只要字串有內容就是truthy 其中,0n是Bigint0。 提供了表示大於 2^53 的整數的功能 (2^53 是 JavaScript 原生的Number能夠表示的最大值) ::: 5. When to use optional chaining? :::info 在物件變數不存在或 null 時回傳 undefined,如果有值的話則會繼續往下取值。 當物件結構越來越複雜時,想要找到物件結構最深層的資料時可使用 ```javascript= const users = [ { name: 'Blueberry', github: { account: 'B-l-u-e-b-e-r-r-y', url: 'https://github.com/B-l-u-e-b-e-r-r-y', repositories: [ { name: 'Discord-Bot-01', url: 'https://github.com/B-l-u-e-b-e-r-r-y/Discord-Bot-01', files: ['discord.js', 'README.md'], releases: [ { version: '1.0', releaseDate: '2021-08-20', description: '...' } ] } ] } }, { name: 'Foo', github: null } ] // 取 releases 的 releaseDate users.map(user => user.github && user.github.repositories && user.github.repositories.length > 0 && user.github.repositories[0].releases && user.github.repositories[0].releases.length > 0 && user.github.repositories[0].releases[0].releaseDate); users.map(user => user.github?.repositories?.[0]?.releases?.[0]?.releaseDate); ``` ::: ## React 6. What's JSX? Why do we need it? :::info * JSX是一種Javascript的語法擴展,允許在Javascript中寫類似HTML的結構。 * 將UI和JavaScript邏輯相融,並組合成元件。 * 本質上做的事情是:生成 React 元素,其實是==React.createElement(component, props, ...children)== 函式的語法糖。 ```javascript= <MyButton color="blue" shadowSize={2}> Click Me </MyButton> React.createElement(MyButton, { color: "blue", shadowSize: 2 }, "Click Me"); ``` Why JSX ? 原因在於現代的許多網站都是高度動態,許多邏輯會決定內容的呈現,這時把內容與邏輯放在一起 ,能確保有任何更動時兩者維持同步,以及在重複使用時也方便。與此同時,跟元件沒有相關的內容,可以放到另一個元件當中,這樣不同元件的改動也可以保持獨立,不怕改某個東西而影響了另一個元件。 ::: 7. How to use useState? :::success 只能在最頂端層呼叫Hook,不要在迴圈、條件式或是巢狀的 function 內呼叫 Hook,這樣才能確保每一次 component render 時 Hook 被呼叫順序都要是一樣的,如此 React 就能正確將內部 State 和對應的 Hook 進行關聯。 ```javascript= import {useState} from 'react'; const [state , setState] = useState(initialState); //設定初初始值 ``` ::: :::info * initialState可以是任意的資料型態,也可以callback funciton,若採用callback funciton,最後需return一個值。 * React re-render的動機:1. setState 被呼叫到 2. state的值確實有改變 * 當在update objectsc或array時,應該replace原本的資料,而非mutate. 谷哥:可以改用 initializer 來設定 state 的初始值,避免不必要的 re-render。 ```javascript= function TodoList() { const [todos, setTodos] = useState(createInitialTodos()); //每次render時都會呼叫一次function function TodoList() { const [todos, setTodos] = useState(createInitialTodos); //只會在初始時呼叫funciton ``` ::: 8. How to use useEffect? :::info ```javascript= const [product, setProduct] = useState(); const { id } = useParams(); useEffect(() => { async function getProduct() { const { data } = await api.getProduct(id); setProduct(data); //當網頁第一次渲染時,會執行function的內容,若不希望第一次執行,可以return掉 } getProduct(); }, [id]); //綁定依賴關係,當data有變動則執行第一個參數的function //若第二個函數是[],則不會重複執行 ``` ::: :::warning 第二個變數類似監聽的感覺,只要其中一個達成便執行。 useEffect執行時機?? 第二個參數放跟不上的差別 unmount啥的 ::: 9. How to use useRef? :::info 1. 不會被re-render影響,useRef也不會觸發re-render。 2. useRef 會回傳一個物件,物件中會有一個名為 current 的屬性,裡面放是一開始給的預設值。 ```javascript= function Carousel() { const [campaigns, setCampaigns] = useState([]); const [activeCampaignIndex, setActiveCampaignIndex] = useState(0); const intervalRef = useRef(); useEffect(() => { async function getCampaigns() { const { data } = await api.getCampaigns(); setCampaigns(data); intervalRef.current = window.setInterval(() => { setActiveCampaignIndex((prev) => prev === data.length - 1 ? 0 : prev + 1 ); }, 5000); } getCampaigns(); }, []); ``` ::: :::warning 不想被render影響時 ::: 10. How to use React Context? :::info 1. 建立一個context的資料夾,專屬於context的空間 2. 在router外層提供context-provider 3. 在需要使用到的component中,import該context,並可用解構賦值的方式取得 谷哥: 1. 一般 Context 會給個好辨認的 prefix,ex: CartTotalNumberContext 2. 一般 Context 會放到另外一個獨立的檔案 ::: :::warning 為什麼要用這個?? ```javascript= export const CartContext = createContext({ cartItems: [], setCartItems: () => {}, }); ``` ::: 11. How to handle form in React? :::info 1. 表單屬性 text inputs, checkboxes, radio buttons等。 2. 初始化狀態 3. 輸入後的變化 onChange? onClick? 要如何獲取input value 4. input value要如何存放? useState? useRef? 6. 提交的邏輯 ```= <Form> <Label htmlFor={id}>{wording}</Label> <Input type={type} id={id} placeholder={placeholder} ref={inputRef} onBlur={handleBlur} /> </Form> ``` ::: ## Libraries 12. How to use Styled Components? :::info ```css= const PageLinkIcon = styled.div` width: 44px; height: 44px; cursor: pointer; background-size: contain; position: relative; `; const PageLinkCartIcon = styled(PageLinkIcon)` background-image: url(${cart}); @media screen and (max-width: 1279px) { background-image: url(${cartMobile}); } `; ``` ```css= import ReactLoading from 'react-loading'; const Loading = styled(ReactLoading)` position: absolute; right: 24px; top: 18px; `; ``` 1. 第一個字要大寫 谷哥:避免把 component 宣告在另外一個 component 裡面。 [Link](https://dev.to/sanjampreetsingh/nested-components-a-bad-practice-reactjs-1hbf) * Can not be export and reused * 執行效率問題:在裡面的component會在外層re-render時被重新create,不僅效率低落,還會遺失先前的State。 ::: :::warning 包components啥的 =>要有className這個props 為什麼backtick可以接在styled components後面 ::: 13. What's the benefit of using Styled Components? :::info 1. 組建化較好管理,干擾的因子較少,提升結構性和可維護性。 2. 產生獨一的名稱。避免相同 className 帶來的麻煩。 3. 自動 Prefix:撰寫最新標準的 CSS,後續的兼容由 Styled Compoents 處理。 ```css -webkit-display: flex; /* 用於WebKit核心的瀏覽器,如Chrome和Safari */ -moz-display: flex; /* 用於Firefox */ -ms-display: flex; /* 用於IE */ ``` 4. 紀錄有哪些元件被渲染到頁面上,並自動地載入所需要的樣式,不會載入多餘的樣式。 5. 主題套用 ::: 14. How to use React Router? :::info sample code: 在index.jsx架構route的配置,在app.jsx架構網頁畫面的配置 ```javascript= import { BrowserRouter, Navigate, Route, Routes } from "react-router-dom"; const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <BrowserRouter> <Routes> <Route path="/" element={<App />}> <Route index element={<Home />} /> <Route path="products/:id" element={<Product />} /> <Route path="checkout" element={<Checkout />} /> <Route path="thankyou" element={<ThankYou />} /> <Route path="profile" element={<Profile />} /> <Route path="*" element={<Navigate to="/" replace />} /> </Route> </Routes> </BrowserRouter> ); ``` ```javascript= import { createBrowserRouter, RouterProvider, Navigate } from "react-router-dom"; const root = ReactDOM.createRoot(document.getElementById("root")); const router = createBrowserRouter([//陣列 { //陣列中放routes物件 path: "/", element: <App />, children: [ { index: true, element: <Home />, }, { path: "products/:id", element: <Product />, }, { path: "checkout", element: <Checkout />, }, { path: "thankyou", element: <ThankYou />, }, { path: "profile", element: <Profile />, }, { path: "*", element: <Navigate to="/" replace />, }, ], }, ]); root.render(<RouterProvider router={router} />); ``` ```javascript= const router = createBrowserRouter( createRoutesFromElements( <Route path="/" element={<App />}> <Route index element={<Home />} /> <Route path="products/:id" element={<Product />} /> <Route path="checkout" element={<Checkout />} /> <Route path="thankyou" element={<ThankYou />} /> <Route path="profile" element={<Profile />} /> <Route path="*" element={<Navigate to="/" replace />} /> </Route> ) ); root.render(<RouterProvider router={router} />); //createRoutesFromElements已在背面創造<Routes></Routes>,因此要改用<Route></Route>來建立巢狀route. ``` Link: 會渲染成`<a>`元素 ```css= const Logo = styled(Link) width: 258px; height: 48px; background-image: url(${logo}); background-size: contain; @media screen and (max-width: 1279px) { width: 129px; height: 24px; } <Logo to="/" /> /* 在return中標明連結 */ ``` ::: :::warning 路由阻擋 useLoaderData ::: 15. What's the benefit of using React Router? :::info 1. 使用 HTML5 History API(現代瀏覽器提供的 API 之一)。這使得 React Router 可以動態更新 URL,而不需要重新加載整個頁面。這對於建構單頁式應用程式(SPA)至關重要,因為它允許應用程序在不同的路由之間切換,同時保持頁面不刷新。 2. 允許定義應用程式的路由配置,可以更清晰地指定哪些組件應該與特定的 URL 匹配。這種配置方式使代碼更容易理解和維護,並有助於預測應用程式的行為。 ::: ## Others - What did you learn from the STYLiSH project? - What did you find which is interesting and you want to share with others? - What did you find which you think you can improve or do it by different way? carousel 按了dot之後會暴走 modular API