# 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)