# W22HW2 簡答題 ###### tags:`React` [TOC] [好讀版( •̀ ω •́ )✧](https://hackmd.io/@ouR5x-oVSMy4d8R5uFsKNg/S1T85OcWK) ## 請列出 React 內建的所有 hook,並大概講解功能是什麼 ### useState :::info :bulb:**state(狀態)** 用來保存用戶的資料,當 state 被改變,會重新 render 畫面,目的是使畫面和用戶的資料保持一致 ::: `const [state, setState] = useState(initialState);` * 回傳一個 state 的值,以及更新 state,state 改變的時候會重新 render component。 * 重新 render 的時候,useState 回傳的第一個值會是最後更新的 state ### useEffect 接收函式,傳遞到 useEffect 的函式會在 render 完成,layout 完成之後執行。 useEffect 所接收的第二個參數(array)可以用來決定何時才要執行 useEffect 的函式。 如果 render 多次 component,在執行下一個 effect 前,上一個 effect 就已被清除。 ### ==useContext== `const MyContext = React.createContext(defaultValue);` * 傳一個預設值(defaultValue) 給`React.createContext()`,`React.createContext()` 會回傳 一個 context object。 `const value = useContext(MyContext);` * `useContext()` 會接收一個 context object(React.createContext 的回傳值)並回傳該 context 目前的值。Context 的值是取決於距離上層 component 最近的 `<MyContext.Provider>` (包住要共用 context 的 component)的值。 * 當 `<MyContext.Provider>` 更新時,會重新 render。 ### useReducer > 就是 redux 的概念 ```javascript= const [state, dispatch] = useReducer(reducer, initialArg, init); const reducer = (state, action) => { return newState } ```` * 當 useState 的邏輯複雜時,適合使用,接受一個函式 reducer,reducer 會回傳現在的 state 以及其配套的 dispatch 方法(dispatch,我的理解是認為它是指 > state相關的邏輯方法)。 * 後面的兩個參數 initialArg 跟 init 則是跟初始化有關。 ### useCallback ```javascript= const memoizedCallback = useCallback( () => { doSomething(a, b); }, [a, b], ); ``` `useCallback()` 的第一個參數是一個 callback,第二個參數是 callback 的 dependency。useCallback 會回傳該 callback 的 memoized 版本,並且只有在 dependency 改變時才會更新。 ### useMemo ```javascript= const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]); ``` `useMemo()` 的第一個參數是一個 callback,第二個參數是 callback 的 dependency。useMemo 會回傳該 callback 的 memoized 的**值**,並且只有在 dependency 改變時才會更新值。 * 優化效能的一種方法,沒有它 React 也必須可以執行才對 ### useRef ```javascript= const refContainer = useRef(initialValue); ``` * useRef 接收參數(initialValue),回傳 mutable object。 可以在當資料改變,不需要再次 render 時使用它。 * 不會改變 component 的 life cycle ### useImperativeHandle ```javascript= useImperativeHandle(ref, createHandle, [deps]) ``` useImperativeHandle 會在使用到 ref 時,向父 component 暴露自定義的 instance 值。 以下面的範例來說,有 render 到 <FancyInput ref={inputRef} /> 的父 component 便能夠能呼叫 inputRef.current.focus()。 ```javascript= function FancyInput(props, ref) { const inputRef = useRef(); useImperativeHandle(ref, () => ({ focus: () => { inputRef.current.focus(); } })); return <input ref={inputRef} ... />; } FancyInput = forwardRef(FancyInput); ``` ### useLayoutEffect 與 useEffect 用法相同,傳遞到 useEffect 的函式會在 render 完成,layout 完成之**前**執行。 ### useDebugValue ```javascript= useDebugValue(value) ``` 用來在 React DevTools 中顯示自訂義 hook 的標籤。 ## 請列出 class component 的所有 lifecycle 的 method,並大概解釋觸發的時機點 整體的順序可以參考[這裡](https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/)。 ### Mounting component 被放到 DOM 的時候觸發的順序如下 * `constructor()`,發生在component 被放到 DOM 之前,通常用來做==初始化 state 和`bind()`== ```javascript= constructor(props) { super(props); // 不要在這裡調用 this.setState() this.state = { counter: 0 }; this.handleClick = this.handleClick.bind(this); } ``` * `getDerivedStateFromProps()`(少用到),發生在 Mounting 和 Updating 的 render() 之前,用來更新 state * `render()`,==檢查==`this.props` 和 `this.state`是否改變並回傳 element(或其他純函數,意思是在不修改 state 的情況下,回傳的值都會是相同的) * `componentDidMount()`,component 被放到 DOM 之後立刻調用 ### Updating 當 component 的 ==props 或 state 更新==,重新渲染(re-rendered) DOM 時會觸發,觸發順序如下 * `getDerivedStateFromProps()`(少用到),發生在執行 render 之前,根據回傳的值來判斷 state 或 props 是否發生變化,當有發生變化則回傳`true`。如果回傳`false`則不會調用`UNSAFE_componentWillUpdate()`,`render()` 和 `componentDidUpdate()`。 * `shouldComponentUpdate()` * `render()` * `getSnapshotBeforeUpdate()`(少用到),發生在最新的一次 render 之前,可以在 component 發生改變之前從 DOM 裡面取得資料,回傳的資料會傳給 `componentDidUpdate()` * `componentDidUpdate()`,發生在 DOM 更新之後立即調用 ### Unmounting component 從 DOM 移除的時候觸發的順序如下 * `componentWillUnmount()`,發生在 component 從 DOM 之上移除之前。 ## 請問 class component 與 function component 的差別是什麼? class component 使用物件導向的寫法並且是透過 `this` 來讀取資料,例如↓,這邊的 this 會在 3 秒之後顯示 user,但這邊會有延遲的問題,如果我們在 3 秒之內又改變了所點選的 user,那麼 this.user 的值也會改變,造成 render 出來的資料不是我們最先點選到的 user。 ```javascript= class ProfilePage extends React.Component { showMessage = () => { alert('Followed ' + this.props.user); }; handleClick = () => { setTimeout(this.showMessage, 3000); }; render() { return <button onClick={this.handleClick}>Follow</button>; } } ``` function component使用函式來寫 component,傳進去的參數不會因為 this 改變而改變 render 用到的資料。 ```javascript= function ProfilePage(props) { const showMessage = () => { alert('Followed ' + props.user); }; const handleClick = () => { setTimeout(showMessage, 3000); }; return ( <button onClick={handleClick}>Follow</button> ); } ``` ## uncontrolled 跟 controlled component 差在哪邊?要用的時候通常都是如何使用? uncontrolled component,沒有使用到 state 的 component。 ucontrolled component,有使用到 state 的 component。 ### ucontrolled component 如何使用 ucontrolled component 自己選到 DOM 元素後去從該 DOM 元素中把值取出來。在 React 中若想要選取到某一元素時,就可以使用 ==useRef== 這個 React Hooks。 ```javascript= const demoComponent = () => { const refContainer = useRef(initialValue); const handleSave = () => { console.log('input is : ', refContainer.current.input) } return ( <input ref={refContainer} /> <Save onClick={handleSave}>儲存</Save> ) } ``` > 資料來源: [1](https://zh-hant.reactjs.org/docs/hooks-reference.html) [2](https://overreacted.io/zh-hans/how-are-function-components-different-from-classes/) [3](https://overreacted.io/a-complete-guide-to-useeffect/) ## 這裡附上強者同學更好的解釋 > 來源https://github.com/Lidemy/mentor-program-5th-Jason-lin80826/pull/26/files#diff-0467cf46875d55ca26da2cd83d4b71efe8818da5f496283128b0051eb0a24cc5 ### 請問 class component 與 function component 的差別是什麼? 在 react-hooks 出現以前 只有 class component 會有 state 可以使用 state 和擁有 lifecycle ,而 functional component 基本上只負責單純呈現資料,有可能是寫死的資料,或是透過 props 傳來的資訊。 但 hooks 的出現改變了這些事情, ### Class component - 需繼承React.Component - 具有生命週期,可以針對某些情境決定是否渲染,ex shouldComponentUpdate() - 具有state (Stateful component) - 需要實作render方法 - ==擁有this==,this 隨時都在變化,props 永遠會拿到 this 對象的資料 ### Functional component - 沒有生命週期 (React Hook useEffect 出現後,就有生命週期了!) - 沒有state(Stateless),所以被稱為無狀態組件(但React Hook useState出現後就可以有state了!) - 可以用arrow function 宣告或是一般的function - ==沒有this==,props會一直是原本傳進來的那個,而不會跟著更新,閉包的概念 - 編譯更快(Functional Component跟Class Component經過babel的編譯,查到一個數據是100bytes v.s 1.2kb