--- 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/)  ## 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)
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up