• 手把手教你用 React Hooks 开发移动端网站,从入门到实践


    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 感兴趣的同学,欢迎来实验楼边敲代码边学习~

  • 相关阅读:
    深入.NET平台和C#编程笔记第三章
    深入.NET平台和C#编程第1章
    深入.NET平台和C#编程笔记第二章
    内部类
    java对象序列化的概念
    HTML第六章
    CIC 抽取滤波器 Verilog Code
    Cordic 算法的原理介绍
    以太网PHY 芯片之 MII/MDIO接口详解
    常见的FPGA内串行数据采样的方式
  • 原文地址:https://www.cnblogs.com/shiyanlou/p/12464862.html
Copyright © 2020-2023  润新知