知名网站建设定制React类组件和函数组件对比-Hooks的介绍及初体验

文章目录

知名网站建设定制的介绍和初体验

Hooks知名网站建设定制出现的原因

Hook 是 React 16.8 知名网站建设定制的新增特性,知名网站建设定制它可以让我们在不编写class的情况下, 使用state知名网站建设定制以及其他的React特性(知名网站建设定制比如生命周期)

知名网站建设定制我们先来思考一下class知名网站建设定制组件相对于函数式组件知名网站建设定制有什么优势?比较常见的是下面这些优势:

class组件可以定义自己的state,用来保存组件自己内部的状态;

import React, { PureComponent } from 'react'// 类组件class HellWorld extends PureComponent {  constructor() {    super()    // 类组件可以在state中保存自己的状态    this.state = {      message: "Hello World"    }  }  render() {    const { message } = this.state    return (      <div>        <h2>{message}</h2>      </div>    )  }}export class App extends PureComponent {  render() {    return (      <div>        <HellWorld/>      </div>    )  }}export default App
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

函数式组件不可以,因为函数每次调用都会产生新的临时变量;

例如下面代码中, 看起来似乎是有保存状态, 但是其实是有两大致命缺陷的

  • 第一: 我们如果有一些操作动态的修改了message这个状态, 其实这个函数组件是不知道要重新渲染的(意味着哪怕修改了message, 页面也不会刷新)
  • 第二: 就算页面重现渲染, 意味着这个函数组件会重新执行, 那么就会重新将最初始的值赋值给message(口水话来说就是, 函数重新执行, 修改了也白修改)
import React, { PureComponent } from 'react'// 函数组件function HelloHooks() {  // 就算函数重新执行, 又会重新赋值, 无意义  let message = "Hello Hooks"  return(    <div>      <h2>{message}</h2>    </div>  )}export class App extends PureComponent {  render() {    return (      <div>        <HellWorld/>        <HelloHooks/>      </div>    )  }}export default App
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

class组件有自己的生命周期,我们可以在对应的生命周期中完成自己的逻辑;

比如在中发送网络请求,并且该生命周期函数只会执行一次;

函数式组件在学习hooks之前,是没有类似于生命周期这样的函数

如果在函数中发送网络请求,意味着每次重新渲染都会重新发送一次网络请求, 这种不必要的重新发送网络请求是非常影响性能的;

class组件可以在状态改变时, 只重新执行以及我们希望重新调用的生命周期函数;

函数式组件在重新渲染时,整个函数都会被执行,似乎没有什么地方可以只让它们调用一次;

所以,在Hook出现之前,对于上面这些情况我们通常都会编写class组件, 没办法在函数组件中编写


类组件存在的问题

复杂组件变得难以理解:

我们在最初编写一个class组件时,往往逻辑比较简单,并不会非常复杂。但是随着业务的增多,我们的class组件会变得越来越复杂;

比如componentDidMount中,可能就会包含大量的逻辑代码:包括网络请求、一些事件的监听(还需要在 componentWillUnmount中移除);

而对于这样的class实际上非常难以拆分:因为它们的逻辑往往混在一起,强行拆分反而会造成过度设计,增加代码的复杂度;

难以理解的class:

对于有些人来说学习ES6的class也 是学习React的一个障碍。

比如在class中,我们必须搞清楚this的指向到底是谁,所以需要花很多的精力去学习this;

虽然我认为前端开发人员必须掌握this,但是依然处理起来非常麻烦;

组件复用状态很难:

在前面为了一些状态的复用我们需要通过高阶组件;

像我们之前学习的redux中connect或者react-router(6版本之前)中的withRouter,这些高阶组件设计的目的就是为了状态的复用;

或者类似于Provider、Consumer来共享一些状态,但是多次使用Consumer时,我们的代码就会存在很多嵌套;

这些代码让我们不管是编写和设计上来说,都变得非常困难;


Hooks的使用注意

Hook的出现,可以解决上面提到的这些问题;

简单总结一下hooks:

它可以让我们在不编写class的情况下, 使用state以及其他的React特性(意味着不学习class关键字和this指向依然可以编写React);

但是我们可以由此延伸出非常多的用法,来让我们前面所提到的问题得到解决;

Hook的使用场景:

Hook的出现基本可以代替我们之前所有使用class组件的地方;

但是如果是一个旧的项目,你并不需要直接将所有的代码重构为Hooks,因为它完全向下兼容,你可以渐进式的来使用它;

Hook只能在函数组件中使用,不能在类组件或者函数组件之外的地方使用;

在我们继续学习Hooks之前,请记住以下几点:

完全可选的: 你在项目中无需重写任何已有代码, 就可以在一些组件中尝试使用Hook。但是如果你不想,你不必现在就去学习或使用 Hook(不使用Hook也是OK的)。

100% 向后兼容的: 没有兼容性问题, Hook 不包含任何破坏性改动。

现在可用: Hook 已发布于 v16.8.0, 现在已经非常稳定, 可以放心使用。


计数器案例的对比

接下来我们通过一个计数器案例,分别使用class组件和结合了hooks的函数式组件进行对比:

类组件的实现

import React, { PureComponent } from 'react'export class Counter1 extends PureComponent {  constructor() {    super()    this.state = {      counter: 10    }  }  changeNumber(num) {    this.setState({      counter: this.state.counter + num    })  }  render() {    const { counter } = this.state    return (      <div>        <h2>当前计数: {counter}</h2>        <button onClick={() => this.changeNumber(-1)}>-1</button>        <button onClick={() => this.changeNumber(1)}>+1</button>      </div>    )  }}export default Counter1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

函数组件的实现, 在下面我有使用一个hook函数useState, 先体验一下, 下一篇文章就会详细 讲解这个hook函数的用法

import { memo, useState } from "react"const Counter2 = memo(() => {  const [ counter, setCounter ] = useState(100)    return (    <div>      <h2>当前计数: {counter}</h2>      <button onClick={() => setCounter(counter - 1)}>-1</button>      <button onClick={() => setCounter(counter + 1)}>+1</button>    </div>  )})export default Counter2
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

可以发现上面的代码差异非常大:

函数式组件结合hooks让整个代码变得非常简洁

并且再也不用考虑this相关的问题;

网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发