欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2022-03-26 22:45:16
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 相关的从业者来说是一次重大变革。

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

今天给大家带来一门 react hooks 的课程react hooks 从入门到实践 ,课程将对 react hooks 做全方位的分析,并通过纯 hooks 函数组件对 cnode 网站进行移动端页面的开发,实战过程中还会介绍前端开发中常用技术栈的使用。

课程实战用到的技术栈 react + react-router+ antd-mobile + axios ,实战部分使用最新 vw 方式做移动端的适配,抛弃 rem 的形式拥抱变化。重写 axios 请求库,做到请求返回统一处理。开发环境的搭建可以作为一个种子项目,方便在工作中启动新项目时直接使用。

项目效果图:

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

教程开始:

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

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

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 服务”,会在浏览器打开一个在线页面,如下图所示。

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

打开浏览器,你会遇到如下报错。

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

原因是实验楼环境启动的在线网址是 https 协议,而项目热更新用的是 ws 协议,所以我们需要将 ws 协议改成 wss 协议。打开项目 node_modules 目录,找到 node_modules/react-dev-utils/webpackhotdevclient.js 脚本,将第 60 行修改为 wss 如下图。

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

重新通过 npm run start 启动项目,再次点开 “web 服务”,如下图所示,便是实验环境配置成功。

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

项目运行的时候有强迫症的同学可以关闭 eslint ,具体方法首先运行指令:

npm run eject

根目录会多出一个 config 文件夹,进入文件夹打开脚本 webpack.config.js,把 eslint 的配置关闭,如下图所示

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

将红框的内容注释之后,重启项目,命令行就会不显示 eslint 语法报错。

篇幅有限,今天就介绍到这里,对 前端 和 react hooks 感兴趣的同学,欢迎来边敲代码边学习~