往期文章目录:

学习 React Hooks

在上一篇 React 17 + Vite + ECharts 实现疫情数据可视化「02 快速搭建项目」 中我们进行了项目的快速搭建,非常高兴能与大家在第 3 篇相见,本篇我们将教大家一些基础的 React 语法,由于本项目是 React 17 版本,因此全局写法采用 React Hooks。

本篇将给大家介绍两个非常重要又常见的两个 Hook,一个是 useState,另外一个是 useEffect,其它的 Hook 暂时不介绍哈,目前的项目版本还不是很需要。思维导图如下,给本文「点赞+评论+关注」三连,支持一下博主哈。

介绍 React

老规矩,先放上 React 官方中文文档 ,以官网最新为准哈,目前我看到的官方版本是 v17.0.2 ,据说 React 18 要来了,快学不动了

以官网简单介绍来说,React 就是:

用于构建用户界面的 JavaScript 库

React 特点

引用自 React 官方中文文档

  • 声明式

    React 使创建交互式 UI 变得轻而易举。为你应用的每一个状态设计简洁的视图,当数据变动时 React 能高效更新并渲染合适的组件。

    以声明式编写 UI,可以让你的代码更加可靠,且方便调试。

  • 组件化

    构建管理自身状态的封装组件,然后对其组合以构成复杂的 UI。

    由于组件逻辑使用 JavaScript 编写而非模板,因此你可以轻松地在应用中传递数据,并保持状态与 DOM 分离。

  • 一次学习,跨平台编写

    无论你现在使用什么技术栈,在无需重写现有代码的前提下,通过引入 React 来开发新功能。

    React 还可以使用 Node 进行服务器渲染,或使用 React Native 开发原生移动应用。

知晓了 React 相关特点,下面由我自己来总结一下吧,说说一些个人感悟:

首先是声明式,这个让我们在编写代码的时候会更直观,就好像我和 React 进行协作一样。

其次是组件化,这个应该很好理解,可以将复杂的视图进行拆分,并且对于某一块共同的视图可以进行复用,这样就做到了「高内聚低耦合」特点。

最后是一次学习,随处编写,这个主要靠虚拟 DOM 来保证实现,其实最开始想到的是 Java 语言,通过虚拟机可以在不同地方使用,而 React 通过虚拟 DOM,使得适用的范围更广了,比如做客户端、网页版、移动端这些都能适用。

介绍 React Hook

先来看看 Hook 简介

Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。

还记得 20 年大三的时候,刚接触 React,那个时候学习 React 大家都觉得很难,我自己使用也是那么觉得,尤其是一些重复性操作,比如创建一个文件,要写上大概如下代码:

class HelloMessage extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
render() {
return (
<div>
Hello {this.props.name}
</div>
);
}
}

那么,既然有这么多重复性的代码,那肯定会有程序员受不了,好家伙,后续在 vscode 里面真出了插件。

因为有一段时间没有使用了,大概记得是当你创建一个 jsx 文件时,输入 rfc 然后按回车就可以生成模版代码了,确实方便许多。

另外,对于 class 语法来说,有一点不自在的点就是 this 这玩意了,经常性要给函数绑定 this,绑来绑去对于我这种新手菜鸡而言 this 一下搞混了,到底谁指了谁?

到大四了,我选择没有学习 React 了,这个学习成本会比 Vue 大一点,当时也没有很长时间给我准备框架底层原理这些,因此当时是以 Vue 为核心进行深度学习,学习底层的一些原理方法。

到后来,因为目前公司技术栈所需,我又重回学习 React 了,没想到版本号就到了 16.8 了,这是一个引起社区重大改动的版本,我开始学习了起来,先找博客,然后看视频,最后再学习官方文档,不能说是掌握很扎实,至少也是学的很有兴趣,自己也做了一些小 demo,现在上手公司项目也不成大问题。

一句话总结:hook 实在是太香了!

接下来,我们主要介绍一下两个 Hook,一个是 useState,另外一个是 useEffect,其它的 Hook 暂时不介绍哈,目前的项目版本还不是很需要。感兴趣的同学们可以自行查阅 React 官方中文文档 学习。

在这里说明一下原因吧,开篇也说明过减少一些学习成本,useState 和 useEffect 是非常常用的两个 Hook,这也是为什么就连官方文档都会将它们排在前面。

使用 useState

官方文档:基础 Hook-useState

基础知识

以下是它的基础语法:

const [state, setState] = useState(initialState);

大家最好是结合官方文档来看。对于这个语法来说的话,又让我联想到 Java 了(毕竟大学里学的就是 Java ,代码也是写的最多),这个语法就好比 getter 和 setter,state 就是我们可以用的值,而 setState 就是设置值, React 官方对于变量命名也是比较规范直观的。

代码示例

下面用官方文档提供的例子来改造一下我们的 App.jsx 文件,代码如下:

import React, { useState } from 'react'

function App() {
const [count, setCount] = useState(0);
return (
<>
Count: {count}
<button onClick={() => setCount(0)}>Reset</button>
<button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
<button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
</>
);
}

export default App

大体界面如下图所示,比较简单,一个显示结果的区域,三个按钮。

“+” 和 “-” 按钮采用函数式形式,因为被更新的 state 需要基于之前的 state。但是“重置”按钮则采用普通形式,因为它总是把 count 设置回初始值。

我们项目当中目前使用来说就如上述代码所示,不会涉及一些「高端操作」,如果已经学会使用的小伙伴可以跳到下一节了。还没有看懂的小伙伴可以把代码自己动手敲一遍,看看实际效果。

使用 useEffect

官方文档:基础 Hook-useEffect

基础知识

以下是它的基础语法:

useEffect(() => {
const subscription = props.source.subscribe();
return () => {
// 清除订阅
subscription.unsubscribe();
};
},[]);

大家最好是结合官方文档来看。对于 useEffect,也是比较重要的 Hook,当初学习 class 语法的时候,componentDidMount 和 componentWillUnmount 这一长串的文字对我这种刚接触 React 的同学来说一下带来了入门到放弃的感觉。

而现在有了 useEffect 来说,不论是编码还是书写规范都顺畅了许多,过去可能写的时候都不知道哪些代码应该写在哪个生命周期函数里面,还要查资料,甚至有时候写错位置了,还在疑惑:诶,这数据怎么没出来,诶,怎么这里是这样的…

虽然说过去 componentDidMount 和 componentWillUnmount 这一长串的文字对于英文水平不是很好的同学刚开始会有一点压力,但是熟悉之后,你会发现这么命名也是一种比较好理解的方式,直接看英文名就知道这个生命周期函数的使用了。

注:useEffect 在 React 的渲染过程中是被异步调用的

注意事项

官方文档:基础 Hook-useEffect 中,还是提及了许多的注意事项。

默认情况下,effect 会在每轮组件渲染完成后执行。这样的话,一旦 effect 的依赖发生变化,它就会被重新创建。

文字理解可能会有点吃力,我们用实际代码来展示一下,继续往下看吧。

代码示例

下面我们继续用上一节的代码来改造一下我们的 App.jsx 文件,代码如下:

import React, { useState, useEffect } from 'react'

function App() {
const [count, setCount] = useState(0);

useEffect(()=>{
console.log('Hello React 17 + Vite App!')
}, [])

return (
<>
Count: {count}
<button onClick={() => setCount(0)}>Reset</button>
<button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
<button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
</>
);
}

export default App

此时,在控制台会打印出 Hello React 17 + Vite App!

这个就类似于 class 语法中的 componentDidMount 生命周期,细心的同学们可能已经发现了,我在 useEffect 中传递了第二个参数,但是是一个空数组,这个是我们下文要讲到的,这是 effect 所依赖的值数组。

我们有时候并不需要在每次组件更新时都创建新的订阅,而是仅需要在某一些变量改变时重新创建。此时可以给 useEffect 传递第二个参数,它是 effect 所依赖的值数组(多个变量通过英文逗号分隔)。

代码示例

在这里,得有一个注意事项,确保数组中包含了所有外部作用域中会发生变化且在 effect 中使用的变量,否则你的代码会引用到先前渲染中的旧变量。

因此,当我们需要依赖于某个变量时,我们不仅要给 useEffect 传递第二个参数,还要在 effect 中使用变量,具体可以参考如下代码:

import React, { useState, useEffect } from 'react'

function App() {
const [count, setCount] = useState(0);

useEffect(()=>{
console.log('Hello React 17 + Vite App!', count)
}, [count])

return (
<>
Count: {count}
<button onClick={() => setCount(0)}>Reset</button>
<button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
<button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
</>
);
}

export default App

当我们点击按钮 + 号 5 次时,控制台打印 5 条信息,诶,这下面不是有 6 条信息嘛,那是因为初次渲染时还是会执行,所以初次执行时 count 还是为初始值 0,所以会打印第一条信息。

联系 & 期待下一篇

项目介绍本篇就到此结束了,让我们期待接下来的文章吧。

博主 21 届本科毕业,可以称呼我 Chocolate,现开通了个人公众号「小狮子前端」,在这里分享我的大厂面试经历,租房攻略,计算机领域那些事儿。

喜欢可以关注一下,还是那句话,现在关注以后就是老粉了,加博主微信可以拉你加入小狮子前端交流|内推群。

希望小伙伴们能够喜欢我的文章,这里是小狮子前端,保持狮子座的热情带给你学习的动力,愿我们成为最好的自己~

QQ交流群:666151691

学如逆水行舟,不进则退