---
# System prepended metadata

title: React
tags: [React]

---

---
tags: React
---
# React

React 本身不算是完整的 framework，搭配其他工具如 React Router、Webpack 等才比較趨近於 framework。本身其實算是用來**建構使用者介面的 js 函式庫**。

> A JavaScript library for building user interfaces.
> ⎯⎯ [React](https://reactjs.org/)

 - 專注於建構 user interface
 - Component based architecture，把整個頁面拆成小塊的元件並 render 出來，高彈性
 - 藉由 component 間傳遞資料，決定 render 的結果
 - React element 只是 JavaScript Object，而非真的把資料顯示到 DOM 畫面上，因此創建 React element 的成本遠低於改變 DOM element 的成本。透過 `ReactDOM.render` 才會真的把 element 顯示出來，在真的 render DOM 之前，會先把 element 建立 snapshot，稱為 **Virtual DOM**（一個仿造 DOM 的 JavaScript 樹狀結構），一直跟上一次的 render 做 diff，**只將有差異的部分更新到 DOM 上**

   > Angular 和 Vue 都是比對資料差異，React 是比對 DOM 差異

 - 執行後的 React component 才會產出 React element，有點像是 Docker image 之於 container

## Component

### Class component

 - Extending from React component object
 - 可以傳遞、接收 props 跟改變 state
 - 需要有 render method

```javascript
export default class Greet extends React.Component {
  render () {
    return <h1>Hi</h1>
  }
}
```

### Functional component

 - 比 class component 更簡易，但不能用原生的 state / lifecycle method

```javascript
export default function App () {
  return <h1>Hi</h1>
}
```

也可以使用 arrow function，懶到極致

```javascript
export default App = () => {
  return <h1>Hi</h1>
}

export default App = () => <h1>Hi</h1>
```

### render

`render()` 必須 return 下面的其中之一種 type：

#### React elements

自定義的 Components。

#### Fragments

 - 不用再自己新增額外的 node 來 group multiple elements

```jsx
render() {
  return (
    <React.Fragment>
      <ChildA />
      <ChildB />
      <ChildC />
    </React.Fragment>
  );
}
```

客家版：

```jsx
render() {
  return (
    <>
      <td>Hello</td>
      <td>World</td>
    </>
  );
}
```

#### [Portals](https://reactjs.org/docs/portals.html)

支援 render 至其他 DOM。常用在 modal、tooltip 等。

### String, numbers, booleans, null

## State

 - State 是被**封裝**在創建自己的 React component instance 中的。任何的其他 Element（不論是上層、下層、還是同層）都無權改變它也不需要知道它的存在。
 - 除了 `constructor` 可直接賦值外，其他地方一定要透過 `setState` 來更新，因為 React 不會自動偵測 state。
 - `setState` 可能會**非同步**的更新 state。這是因為 React 因為要增進效能，所以會把一段時間內的多個 `setState` 批次（Batch）執行。也就是，`this.setState` 後立即拿 `this.state` 取得的值有機會是舊的。
    這也是為何我們必須在需要當前 state 或 props 的值時使用 setState updater 參數的原因：

    ```jsx
    // Wrong
    this.setState({
      counter: this.state.counter + this.props.increment,
    });

    // Correct
    this.setState((state, props) => ({
      counter: state.counter + props.increment,
    }));
    ```

 - React App 是**單向資料流**（Unidirectional data flow），下層的 component 只單純接收上層 component 傳下去的值，且上層 component 的 state 也只能影響到它之下的 component。這種資料由上往下（top-down）的概念就像水流一樣。

## [Lifecycle](https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/)

![](https://i.imgur.com/CQQMkAV.png)
    
## Constructor

 - 最一開始應先呼叫 `super(props)` ，否則 `this.props` 不會被 defined。
 - 使用時機：**initializing local state**, **binding event handler**。
 - 在此不該呼叫 `setState` ，直接賦值即可。
 - 避免 side-effects 或 subscriptions，這些應該被放在 `componentDidMount` 。

## getDerivedStateFromProps

 - It enables a component to update its internal state as the result of changes in props.

## Hook

以 `use` 為命名開頭，讓 component 可以共用 function，或是把複雜的 code 藏起來。

---

https://create-react-app.dev/docs/getting-started/

create react app 已經把 webpack 包在裡面，但有些 package 就需要改 webpack，craco 會把要寫到 webpack 裡，就不用自己 eject（這個下了就不可逆），例如要用 SASS 時就要用 craco 幫忙

```shell
$ npm install -g create-react-app
$ npx create-react-app demo
```

> npx? 有點像 pipenv

npm install package

state hook
useState 回來是一個 tuple
function 比較主流～？
redux 用 store 把所有 state 集中管理，component 會 dispatch action，action 去更新 sotre 裡的 state
component 其實直接 `export default` （import 時不用加 `{}`），function 比較多 `export`  （import 時加 `{}`）

containers: conatainer 喂 component props，component 吃資料後吐回 template，container 去打 API 把資料拉回來，再把資料當成 props 餵回去，例如要畫圓餅圖時，資料來源不一樣，但 template 是相同的，就很適合這樣用

[style components](https://styled-components.com/): CSS `$ npm install styled-components`

material-UI, semantic-ui 都是票釀的 UI framework

https://www.creative-tim.com/templates/react 有提供很多漂亮的 template

https://github.com/axios/axios call API

cdn 圖片大小可以根據 device 大小決定回傳的圖檔

tailwindcss 很棒棒的 CSS

https://github.com/brillout/awesome-react-components 有很多很棒滴 components
react-spring 做動畫

做一個 todo list


React.Suspense?
Route?

## 參考資料

 - [I Want To Know React](https://ithelp.ithome.com.tw/articles/10243620)