React 已經是 JavaScript 生態系統中最受歡迎的前端框架之一,盡管人們已經對它贊不絕口,但 React 團隊仍然在努力讓它變得更好,
在 2018 ReactConf 大會上,React 官方發布了 Hooks,隨后它席卷了整個 React 開發界,
React Hooks 是 React 庫的新增功能,它允許你撰寫狀態邏輯并使用其他 React 功能,同時無需撰寫類組件,你甚至可以單獨使用 Hooks 來制作自己的應用程式,這對 React 相關的從業者來說是一次重大變革,
今天給大家帶來一門 React Hooks 的課程React Hooks 從入門到實踐 ,課程將對 React Hooks 做全方位的分析,并通過純 Hooks 函陣列件對 CNode 網站進行移動端頁面的開發,實戰程序中還會介紹前端開發中常用技術堆疊的使用,
課程實戰用到的技術堆疊 React + React-Router+ Antd-Mobile + Axios ,實戰部分使用最新 vw 方式做移動端的適配,拋棄 rem 的形式擁抱變化,重寫 Axios 請求庫,做到請求回傳統一處理,開發環境的搭建可以作為一個種子專案,方便在作業中啟動新專案時直接使用,
專案效果圖:
教程開始:
React 作為 Facebook 推出的前端主流框架之一,在版本升級上一直是采用平滑升級的模式,在升新版本的時候,無論是增加或者洗掉了某些 API,React 都能做到版本向后兼容,也就是用舊版本的寫法,最新的 React 包也能做到基本支持,這次也不例外,在 v16.8 版本引入了全新的 API,名叫 React Hooks,參考官方的解釋就是三個點
- 完全可選的,你無需重寫任何已有代碼就可以在一些組件中嘗試 Hooks,但是如果你不想,你不必現在就去學習或使用 Hooks,
- 100% 向后兼容的,Hooks 不包含任何破壞性改動,
- 現在可用,Hooks 已發布于 v16.8.0,
React 官方沒有計劃從 React 中移除 Class,但是我相信不久的將來,Hooks 將被大范圍使用,相比之下 Hooks 可以涵蓋所有 Class 組件的應用場景,且提供了更高的靈活性、可測驗性和代碼的復用能力,Hooks 不會影響你對 React 概念的理解,恰恰相反,Hooks 為已知的 React 概念提供了更直接的 API:props, state,context,refs 以及生命周期,在后面的章節里,筆者還會一一介紹上面列出的 API,
Dan Abramov 在社交他的社交網站上也毫不吝嗇的給出了他的想法,
Hooks 將會是 React 的未來,
我們為什么不再需要 Class 組件
存在即是合理的,React Hooks 要解決的問題是狀態共享,是繼 render-props 和 higher-order components 之后的第三種狀態共享方案,不會產生 JSX 嵌套地獄問題,這個狀態指的是狀態邏輯,所以稱為 狀態邏輯復用會更恰當,因為只共享資料處理邏輯,不會共享資料本身,
在 React Hooks 推出之前,React 便已經有函陣列件了,那么已經有了函陣列件,為什么開始還要引入 Class 組件呢?
早些時候的 React 組件以有無狀態(state)分為兩種,代碼如下,
// 有狀態組件
class Hello extends React.Component {
constructor(props) {
super(props)
this.state = {
text: 'Hello World'
}
render() {
return <div>{text}</div>
}
}
}
// 無狀態組件
// 狀態通過父組件傳入
const Hello = (props) => <div>{props.text}</div>
我們可以通過 Class 組件的 this 背景關系去保存和訪問狀態(state),但是函陣列件在其作用域內很難維持住這個狀態,試想如果再次運行函式的話,所有的狀態都將被重置,所以我們才一直使用 Class 的形式撰寫有狀態組件,
Hooks 撰寫函陣列件,它的狀態是如何維持的呢
了解過 React Fiber 的同學應該知道,類組件中的狀態其實保存在 Fiber 的屬性 memoizedState 上,并不是在 Class 的 this.state 上,那么回過頭來看 React Hooks 組件的狀態,其實也是去訪問 Fiber 上的 memoizedState 屬性,這樣看來,問題就迎刃而解了,
兩種寫法的對比分析
繁重的寫法,
下面是一段簡單的以 Class 形式書寫的組件代碼,
import React, { Component } from "react";
export default class MyButton extends Component {
constructor() {
super();
this.state = {
text: "點擊"
};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState({
text: "改變"
});
}
render() {
const { text } = this.state;
return <button onClick={this.handleClick}>{text}</button>;
}
}
僅僅是需要一個按鈕組件,代碼量已經接近 20 行之多,可能你會覺得 20 行并不多,但是當組件內部需要控制一些狀態的時候,那代碼量就不僅僅是 20 行這么簡單了,包括整個 React 專案都是由各個組件拼裝而成,層層嵌套,再加上狀態管理插件如 Redux、Mobx 等,就會是一場 “災難”,
反觀 Hooks 的寫法:
import React from "react";
export default const MyButton = () => {
const [text, setText] = useState('點擊')
return <button onClick={setText('改變')}>{text}</button>
}
在 Hooks 出現之前,React 也是可以用函式寫組件的,但是只能寫一些無狀態的純組件 (Pure Component) ,也就是內部是不能有屬于自己的狀態變數,上述代碼中 Hooks 實作了函陣列件管理自身狀態的方式,不僅在代碼量上得以控制,書寫上也簡便了不少,受限于現代瀏覽器,所有最新 ES6 + 的寫法,不是所有瀏覽器都會支持,類組件的寫法在經過 babel 編譯后會編譯成 ES5 寫法,才能讓各大瀏覽器得以支持和運行,這就導致了編譯后類組件比函陣列件多一層繼承 React.Component 的代碼,從這個角度出發,Hooks 寫法降低了編譯后的代碼了減少 bundle 包的大小,
復雜組件變得難以理解,
隨著組件代碼的增多,狀態與狀態緊密相連,想把組件拆分的細致那就變得難上加難,重復的邏輯在不同的組件和生命周期函式之間不斷出現,到那時專案就變得不可維護,
開發環境的搭建
課程總共為 10 章,1 ~ 8 章以實體和原理講解為主,9 ~ 10 章 為實戰章節,
所以 1 ~ 8 章筆者只需要通過官方提供的專案初始化工具 create-react-app 來完成課程內部代碼的講解,
首先電腦里必須事先安裝 Node 環境,
檢測當前 Node 版本和 NPM 版本,執行命令列,
node -v
npm -v
如果已經安裝過的同學會列印出相應的 Node 版本,當然實驗樓也提供了前端的開發環境,內置 Node 和 NPM,已經在全域安裝了 cnpm 包,同學盡量使用 cnpm 安裝 node_modules 包,因為有些包是放在國外的服務器,直接使用 npm 可能會安裝不上或者需要很久的時間,對大家的開發體驗也是不好的,
全域安裝 create-react-app,
cnpm install create-react-app -g
安裝完畢之后,通過指令可以生成專案,
// my-app 為專案檔案夾的名字,可自定義
npx create-react-app my-app
or
npm init react-app myapp
初始化專案結束之后,進入進入檔案夾,通過 npm run start 啟動專案,默認的埠會是 3000,而實驗樓在線開發環境只對外開放 8080 埠,所以我們要對檔案里的腳本做一些改動,
有兩種方式改變 create-react-app 初始化專案的開發環境啟動埠,
- 修改 package.json 的 scripts 屬性,
"scripts": {
"start": "PORT=8080 react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
要注意的是,如果是 Windows 用戶建議在 PORT 前加上一個 cross-env,需要通過 cnpm install cross-env -D 下載到開發依賴 devDependencies 中,
cross-env 是一個運行跨平臺設定和使用環境變數的腳本 .cross-env 使得您可以使用單個命令,而不必擔心為平臺正確設定或使用環境變數,
- 通過修改 node_modules/react-scripts/scripts/start.js 腳本第 60 行的埠號,如下,
// line 60
const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 8080;
埠修改完之后,點開右邊的 “Web 服務”,會在瀏覽器打開一個在線頁面,如下圖所示,
打開瀏覽器,你會遇到如下報錯,
原因是實驗樓環境啟動的在線網址是 https 協議,而專案熱更新用的是 ws 協議,所以我們需要將 ws 協議改成 wss 協議,打開專案 node_modules 目錄,找到 node_modules/react-dev-utils/webpackHotDevClient.js 腳本,將第 60 行修改為 wss 如下圖,
重新通過 npm run start 啟動專案,再次點開 “Web 服務”,如下圖所示,便是實驗環境配置成功,
專案運行的時候有強迫癥的同學可以關閉 eslint ,具體方法首先運行指令:
npm run eject
根目錄會多出一個 config 檔案夾,進入檔案夾打開腳本 webpack.config.js,把 eslint 的配置關閉,如下圖所示
將紅框的內容注釋之后,重啟專案,命令列就會不顯示 eslint 語法報錯,
篇幅有限,今天就介紹到這里,對 前端 和 React Hooks 感興趣的同學,歡迎來實驗樓邊敲代碼邊學習~
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/25153.html
標籤:Android
