---
# System prepended metadata

title: React
tags: [npm, react]

---

# React

## 環境

開始建立react專案，為(prj_react)
npx是npm 內建的一個指令，安裝完畢後就會把安裝檔刪除，不佔空間，可以指定套件版本。
也可在建立的資料夾中，執行cmd，create-react-app

``` command
npx create-react-app prj_react

create-react-app prj_react
```

完成跑完後

```command
Success! Created ec-shopping24 at C:\....\prj_react
Inside that directory, you can run several commands:

  npm start
    Starts the development server.

  npm run build
    Bundles the app into static files for production.

  npm test
    Starts the test runner.

  npm run eject
    Removes this tool and copies build dependencies, configuration files
    and scripts into the app directory. If you do this, you can’t go back!

We suggest that you begin by typing:

  cd prj_react
  npm start

Happy hacking!
```
且進行`npm start` 會跳出`localhost:3000`

![npm start](https://i.imgur.com/hmA7E2d.jpg)

### package.json

CRA 做好語意轉譯

### 主要檔案

public/index.html，`頁面模版`
src/index.js，`JavaScritp entry point`
import src/App.js，`module名App`，Root component

***`sfc`，react快速格式***

#### 檔案結構

``` text
demo_app_using_cli
├── README.md
├── node_modules
├── package.json
├── .gitignore 
├── public                         // 放置靜態檔的資料夾
│   ├── favicon.ico
│   ├── index.html 
│   └── manifest.json
└── src                            // 放置即將被編譯檔案的資料夾
│    ├── assets
│        ├──image                  // 圖檔資源(img,icon)
│        └──style                  // Style 共用區（font,color,style）
│    ├── components                // 元件
│    ├── containers                // Connect 後的元件放置區
│        └── screens               // 頁面 Container
│    ├── ducks                     // Redux & Saga 檔案結構
│    │    ├── flows                // Saga 非同步管理
│    │    │   └── api              // API 管理
│    │    │       └── http.js      // fetch
│    │    ├── modules              // Redux State 管理
│    │    └──selectors.js          // Redux getState 定義 
│    ├── routes                    // 路由管理 
├── App.css
├── App.js                         // App 主要入口
├── App.test.js
├── index.css
├── index.js                       // 整個 App 的 entry point
├── logo.svg
└── serviceWorker.js
└── setupTests.js
```

```command
npm init // 初始化 npm 專案
git init 

npm i --save react react-dom
npm i -D babel-loader @babel/core 
npm i -D @babel/preset-env @babel/preset-react 
npm i -D webpack webpack-cli webpack-dev-server
npm i -D html-webpack-plugin
// --save-dev === -D
```

```graphviz
digraph hierarchy {

    nodesep=1.0 // increases the separation between nodes

    node [color=Red,fontname=Courier,shape=box] //All nodes will this shape and colour
    edge [color=Blue, style=dashed] //All the lines look like this

    App->{Narbar BlogDetails Sidebar} 
    Narbar->{}
    BlogDetails->{}
    Sidebar->{Categories Tags}

    {rank=same;Categories Tags}  // Put them on the same level
}
```

Websites

```graphviz
digraph hierarchy {

    nodesep=1.0 // increases the separation between nodes

    node [color=Red,fontname=Courier,shape=box] //All nodes will this shape and colour
    edge [color=Blue, style=dashed] //All the lines look like this
    
    websites ->{NonReact React} 
    NonReact ->{ page }[label = "發送需求 "][dir="both"]
    React ->{ page react }[label = "發送需求 "][dir="both"]
    page ->{index jsBundle}[dir="both"][label = "回傳頁面 "]
    index -> {server}
    react -> {server}[dir="both"][label = "component.js/updata DOM "]
    react -> {jsBundle}
}
```




## JSON & API

### JSON

先行安裝NPM[^first]JSON，建立相關資料夾路徑及資料

``` command
npm i -g json-server


npm i = npm install
npm -g = 全域
```

開啟 JSON Server

``` command
json-server --watch 路徑及檔案名稱 --port 8800
json-server --watch db.json //範例
```

``` command
npm i json-server --watch data/db.json --port 8800
```

### API

* PUT 修改資料(完整、會將原本包含的刪除)
* PATCH 修改資料(局部、只更動修改部分)
* GET 取得

```text
ALL：/blogs/

登入：/blogs/{id}
```

* POST 新增資料

```text
新的一篇：/blogs
```

* DELETE 刪除

```text
刪除一篇：/blogs/{id}
```

## JSX

> **官方<i class="fa fa-arrow-right"></i>** JSX是一種 JavaScript 語法的擴展。它跟模板語言類似，但具有JavaScript的全部功能。
> 
> JSX會被編譯為`==React.createElement()==`，然後返回被稱為React element的JavaScript object。JSX 的基本簡介可以參見，更深入的教程可以參見。 
> 
> React DOM 使用camelCase來命名 HTML 屬性名稱。例如，==tabindex== 在 JSX 中寫作 ==tabIndex==。而 ==class==因為是 JavaScript 中的保留字，所以寫作 ==className==：[color=rgb(97, 218, 251)]

``` react
const name = 'Clementine';
ReactDOM.render(
  <h1 className="hello">My name is {name}!</h1>,
  document.getElementById('root')
);
```

JSX中所有元素都需要**關閉**，類似XML

``` react
<div>content</div> 或 <img />
/*  (self-closing) */
```

事件觸發需使用**駝峰式**命名

``` react
<div onClick={() => console.log('click test'}>Click Me</div>
```

style 屬性要以 JS 物件的格式撰寫，採用駝峰式命名法而非-，單位要用單引號包住 (例: '50%')。外面則要再加上一層大括號。

``` react
<p style={{fontSize: '15px',marginTop: '20px'}}>Some text</p>

HTML 
<div class="App"></div>
JSX 
<div className="App"></div>

```

### Element

``` react
const element = <h1>Hello, world</h1>;
```

### Components

``` react
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}
```

ES6：

``` react
class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}
```

### props

> **官方<i class="fa fa-arrow-right"></i>** props 是 React component 的輸入。它們是從父 component 傳遞到子 component 的數據。
> 
>請記著 ==props== 是只讀的。不應該以任何方式來修改它們。
>
>如果你需要修改某些數值來反映用戶輸入或網絡響應，請使用 ==state== 來代替。[color=rgb(97, 218, 251)]

```react
// ❌錯誤!
props.number = 42;
```

### state

> **官方<i class="fa fa-arrow-right"></i>** ==props== 與 ==state== 的差異在於，==props==是由父component傳遞，而 ==state==是由component本身管理的。一個component不能改變自己的 ==props==，但就可以改變自己的==state==。[color=rgb(97, 218, 251)]

### Keys

### Refs

#### 元件操作

emmt：sfc

``` react
const Button = () => {
const handleClick = (name) =>{
    console.log('hello' + name);
}

return ( 
    <div className="o-btn" onClick={() => handleClick('is me')}>button</div>
);
}

export default Button;
```

## Basic Hooks

> **官方<i class="fa fa-arrow-right"></i>** Hook 是 React 16.8 中增加的新功能。它讓你不必寫 class 就能使用 state 以及其他 React 的功能。[color=rgb(97, 218, 251)]

```react
function Appp () {
    ✅ const [state, setState] = useState()
    ❌ if (true) { useState() }
    ❌ function B () { useState() }
    ❌ for(xx) { useState() }  
}

const Example = (props) => {
  // 你可以在這裡使用 Hook！
  return <div />;
}

function Example(props) {
  // 你可以在這裡使用 Hook！
  return <div />;
}
```

### useState

state變數可以是object或是array，會回傳一個包含兩個值的array，第一個值是 state、第二個值是用來更新state的函式。每當state值改變，就會觸發render。

```react
import React, { useState } from 'react';

function Example() {
  // 宣告一個新的 state 變數，我們稱作為「count」。
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}
```

### useEffect

任何會產生 side Effect 的行為都應該 Effect Hook 裡執行。他和 componentDidMount，componentDidUpdate，與 componentWillUnmount 有著同樣的宗旨，但整合進一個單一的 API。

### useContext

### 額外的hook

* useReducer
* useCallback
* useMemo
* useRef
* useImperativeHandle
* useLayoutEffect
* useDebugValue

## 資料來源

* [The Net Ninja - youtube](https://youtu.be/0sSYmRImgRY)
* [Hooks API Reference](https://reactjs.org/docs/hooks-reference.html#usestate)
* [[React Hook 筆記] 從最基本的useState, useEffect 開始](https://medium.com/hannah-lin/react-hook-%E7%AD%86%E8%A8%98-%E5%BE%9E%E6%9C%80%E5%9F%BA%E6%9C%AC%E7%9A%84-hook-%E9%96%8B%E5%A7%8B-usestate-useeffect-fee6582d8725)

## 註腳

註腳 1 NPM相關指令

[^first]: [NPM](/hgzv1PGsT8Cyan_YFJR86w)相關指令

###### tags: `react` `npm`


## 其他相關

[React Router](/pXzLPLFGQmmkPCsDzPl41Q)