React18.2.0入门教程(三)

前言

这篇文章主要是梳理下官网对于State和react生命周期函数知识内容,有感兴趣的开发者可以去react官方文档参考其详细的说明

State

之前已经提到过,函数式组件没有state属性,因此,本节我们需要切换成类式组件进行演示

使用类式组件需要创建一个新的类,如App,通过新创建的类继承 React.Component这个内置的组件类。因为使用类作为数据类型构造,所以需要使用构造器来初始化类成员,这个知识点在es6的类中有详细说明,对这方面不是很熟悉的开发者可以去查询相关资料辅助学习

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {data: {name: 'lily', age: '18'}}
  }
}

在这里,类式组件通过构造器的第一个参数接收父组件传递过来的值,之前的函数式组件则是通过本身的形参来接收。这里要注意的点是,类式组件的构造器内如果需要接收props,也就是外部传来的值的话会比函数式组件多一个步骤:super(props)。这是因为我们是继承react内部类,外部传入过来的props会直接到我们的新类中,而不会到react的类中,所以需要通过super调用父类构造函数传递props

分析

在这里,为了便于更直观看到state的作用,可以为这个类添加一个函数,这个函数会输出目前的this指针变量,也就是继承后的 App 类,并在render函数执行时调用它,以下是App.js文件内全部代码

// 因为用到了React这个模块,因此需要导入
import React from "react";

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { data: { name: 'lily', age: '18' } };
  }
  render() {
    return <div>{this.showInfo()}</div>;
  };

  showInfo() {
    console.log(this);
  }
}

// 需要导出给index.js文件使用
export default App

这样,App.js文件内的代码我们就写好了,并且因为脚手架内部帮我们做好了处理,因此能够原生支持JSX语法。现在开始写index.js文件内的代码吧,还记得我们之前是怎么写的吗?之前创建好一个函数式组件后,需要获取到要挂载的节点,然后将那个节点转变为react根节点,之后使用根节点的render方法渲染组件

// 使用 react-dom/client 替换了静态脚本的 ReactDOM
import ReactDOM from 'react-dom/client'
// 导入我们需要用到的组件
import App from './App'
// 后续两步合成一行代码:使用createRoot函数将dom节点转为react节点,然后调用render方法渲染组件
ReactDOM.createRoot(document.querySelector('#root')).render(<App />);

现在也是一样的,只不过细微之处会有所改变,如上

注意,组件首字母在这边依然是需要大写,遵循和之前一样的原则

规整

现在,让我们看下浏览器控制台的输出结果

确实输出了App类内部的信息,其中涉及到之后要讨论的内容:context和refs

现在我们可以使用this指针访问到state保存的内容了。state就是App这个组件内管理的状态,内部的数据都会变成响应式的,如果需要更改其中的数据,需要使用到setState函数

注:除构造函数内外如果直接对state进行赋值可能会导致未知的错误,同时也会给维护state造成巨大的困难,极易影响开发效率

修改state

如果需要修改state的话需要使用setState函数。不过该函数只能覆盖原有的state,不能对state内部进行精细化操作。举个栗子,现在的state是个对象,里面是这样的:data: {name: 'lily', age: '18'}。那么,如果想要修改age,或者删除age这个属性,就需要写一个全新的对象覆盖掉之前的对象

this.setState({ data: { name: 'lily' } });

我需要删除age这个属性,所以我将需要的值使用setState函数重新赋值了一遍,而新的成员中没有age这个属性。正如这个函数的名称,不是修改,也不是删除,而是设置。可能你会觉得这样是不是太冗余了?万一这个state嵌套很复杂呢?是的,这个疑问是正常的,不过请放心,react内部会帮我们做好相应的优化,如果确实需要修改的话建议将state复制下来然后将修改好的数据使用setState再赋值一次

生命周期方法

react也有和vue类似的一个生命周期系统,因为定义在类内所以称为方法,其实就是函数。因为我们学习的是react18,因此,这里展示的是更新后的react生命周期方法,有兴趣的开发者可以前往csdn查询旧版本的生命周期方法

react生命周期是react应用从创建到销毁的一个过程,而生命周期方法则是react提供的在这个生命周期内可供我们操作的内置函数,它能够在某些时刻下注入我们的业务代码,从而避免过早执行或延误执行我们编写的逻辑代码

以下为新版react的生命周期方法:

static getDerivedStateFromProps(nextProps, prevState)

指从更新后的props中获取State,它可以让组件在 props 发生改变时更新它自身的内部 state。 react类组件中的静态方法,在render 前调用,在初始挂载以及后续更新时都会被调用。返回值建议为一个对象来更新 state,如果返回 null 则不更新任何内容

接收两个参数,一个是传进来被更改后的 nextProps 和之前的 prevState,即state被更改前的值。该参数由react自动传送过来,只需理解这两个参数表达的意思并善加使用即可

使用场景:可以在props发生改变时使用这个函数对state做出一些改变

shouldComponentUpdate(nextProps,nextState)

在组件将要更新前执行,在render前调用,此时可以拿到更新后的props和state,接收两个参数,第一个指更新后的props,第二个指更新后的state。其返回值为bool值决定了是否执行render函数,为false则不执行

getSnapshotBeforeUpdate(prevProps, prevState)

在创建完虚拟DOM节后准备渲染为真实DOM之前,它使得组件能在发生更改之前从 DOM 中捕获一些信息。在render后调用,此时state已经更新完毕。接收两个参数,第一个指更新前的props,第二个指更新前的state。此生命周期方法返回的任何值都将作为componentDidUpdate 的第三个参数

使用场景:可以在渲染前拿到更新前的props和state进行操作

componentDidMount()

在组件完成挂载后执行,此时已经完成dom树的更新

componentDidUpdate(prevProps,prevState,snapshot)

在组件完成更新后执行,初始化完成时不会被调用。在render后调用,此时dom节点已经更新完毕。接收三个参数,第一个指更新前的props,第二个指更新前的state

第三个则是getSnapshotBeforeUpdate执行后返回的值

componentWillUnmount()

在组件将要卸载时执行,一般在这里做善后或收尾工作,如:清除定时器,释放闭包函数变量

以下为react新版后的生命周期流程图,可供各位开发者参考

尾声

因为工作等原因,这个教程断断续续的,实在不好意思。这个问题我现在也没法解决,不过我会尽可能地保持更新,希望能得到各位的支持,感谢

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值