---
# System prepended metadata

title: W22HW2 簡答題
tags: [React]

---

# 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
