手把手教你用 React Hooks 開發移動端網站,從入門到實踐

来源:https://www.cnblogs.com/shiyanlou/archive/2020/03/11/12464862.html
-Advertisement-
Play Games

React 已經是 JavaScript 生態系統中最受歡迎的前端框架之一 。儘管人們已經對它贊不絕口,但 React 團隊仍然在努力讓它變得更好。 在 2018 ReactConf 大會上,React 官方發佈了 Hooks ,隨後它席卷了整個 React 開發界。 React Hooks 是 R ...


React 已經是 JavaScript 生態系統中最受歡迎的前端框架之一。儘管人們已經對它贊不絕口,但 React 團隊仍然在努力讓它變得更好。

在 2018 ReactConf 大會上,React 官方發佈了 Hooks,隨後它席卷了整個 React 開發界。

React Hooks 是 React 庫的新增功能,它允許你編寫狀態邏輯並使用其他 React 功能,同時無需編寫類組件。你甚至可以單獨使用 Hooks 來製作自己的應用程式,這對 React 相關的從業者來說是一次重大變革。

image

今天給大家帶來一門 React Hooks 的課程React Hooks 從入門到實踐 ,課程將對 React Hooks 做全方位的分析,並通過純 Hooks 函數組件對 CNode 網站進行移動端頁面的開發,實戰過程中還會介紹前端開發中常用技術棧的使用。

課程實戰用到的技術棧 React + React-Router+ Antd-Mobile + Axios ,實戰部分使用最新 vw 方式做移動端的適配,拋棄 rem 的形式擁抱變化。重寫 Axios 請求庫,做到請求返回統一處理。開發環境的搭建可以作為一個種子項目,方便在工作中啟動新項目時直接使用。

項目效果圖:

image

教程開始:

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 在社交他的社交網站上也毫不吝嗇的給出了他的想法。

image

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 服務”,會在瀏覽器打開一個線上頁面,如下圖所示。

image

打開瀏覽器,你會遇到如下報錯。

image

原因是實驗樓環境啟動的線上網址是 https 協議,而項目熱更新用的是 ws 協議,所以我們需要將 ws 協議改成 wss 協議。打開項目 node_modules 目錄,找到 node_modules/react-dev-utils/webpackHotDevClient.js 腳本,將第 60 行修改為 wss 如下圖。

image

重新通過 npm run start 啟動項目,再次點開 “Web 服務”,如下圖所示,便是實驗環境配置成功。

image

項目運行的時候有強迫症的同學可以關閉 eslint ,具體方法首先運行指令:

npm run eject

根目錄會多出一個 config 文件夾,進入文件夾打開腳本 webpack.config.js,把 eslint 的配置關閉,如下圖所示

image

將紅框的內容註釋之後,重啟項目,命令行就會不顯示 eslint 語法報錯。

篇幅有限,今天就介紹到這裡,對 前端 和 React Hooks 感興趣的同學,歡迎來實驗樓邊敲代碼邊學習~


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 第四章索引和事務 1. 什麼是索引?有什麼用? 1)索引是資料庫對象之一,用於加快數據的檢索,類似於書籍的目錄。在資料庫中索引可以減少資料庫程式查詢結果時需要讀取的數據量,類似於在書籍中我們利用索引可以不用翻閱整本書即可找到想要的信息。 2)索引是建立在表上的可選對象;索引的關鍵在於通過一組排序後的 ...
  • 第三章組函數和表關係 字元串函數 -- concat 連接兩個字元串 select concat('abc','ABC') from dual; select 'abc'||'ABC' from dual; select concat(first_name,'_')||last_name con,t ...
  • 第二章 Oracle體系架構和導入/導出 Oracle體繫結構 服務名,實例名,orcl n Oracle通過資料庫實例來載入和管理資料庫,每個運行的Oracle資料庫都對應一個Oracle實例(Instance),也可以稱為常式。 n 當資料庫伺服器上的一個資料庫啟動時,Oracle將為其分配一塊 ...
  • Oracle 與Mysql 對比: MySQL: 免費;小型企業;僅是資料庫;輕 Oracle:收費, 中大型企業;資料庫服務(許可權,併發,事務,一致性);更適合集群;重 共同點:都屬於關係型資料庫 RDBMS 非關係型資料庫NoSQL(Not Only SQL ): Redis,Mongodb,S ...
  • 查詢緩存: MySQL提供的數據緩存QueryCache,用於緩存SELECT查詢的結果 預設不開啟,需要在配置文件中開啟緩存(my.ini/my.cnf) 在[mysqld]段中,修改query_cache_type完成配置: 0:關閉 1:開啟,但是預設緩存,需要增加sql-no-cache提示 ...
  • 1.前言 有時候,我們需要把A庫A1表某一部分或全部數據導出到B庫B1表中,如果系統運維工程師沒打通兩個庫鏈接,我們執行T-SQL是處理數據導入時會發生如下錯誤: 這時候SQL Server導出功能很好彌補這一點,而該章節重點介紹該功能。 2.操作 資料庫版本:Microsoft SQL Serve ...
  • MySQL優化中,最重要的優化手段就是索引,也是最常用的優化手段 索引簡介: 索引:關鍵字與數據位置之間的映射關係 關鍵字:從數據中提取,用於標識,檢索數據的特定內容 目的:加快檢索 索引檢索為什麼快: (1)關鍵字相對於數據本身,量較小 (2)關鍵字都是排序好的 MySQL中索引的類型: 普通索引 ...
  • 從0系統學Android 52 發送廣播 本系列文章目錄 : "更多精品文章分類" 本系列持續更新中.... 初級階段內容參考《第一行代碼》 5.3 發送自定義廣播 前面已經學習瞭如何接受廣播了,下麵來學習如何發送自定義廣播,廣播類型分為:標準廣播和有序廣播,下麵分別來說一下這兩種廣播如何發送。 5 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...