React 组件进阶

2022-11-07 14:56:58 浏览数 (1)

目录

1、 props 深入

1.1 children 属性

1.2 props 校验

2、组件的生命周期

2.1 生命周期 - 挂载阶段

2.2 生命周期 - 更新阶段

2.3 生命周期 - 卸载阶段


1、 props 深入

1.1 children 属性

  • children 属性:表示组件标签的子节点。当组件标签有子节点时,props 就会有该属性
  • children 属性与普通的props一样,值可以是任意值(文本、React元素、组件,甚至是函数,jsx)

如果我们像上面 ListItem 标签里面写上东西 ,这样就相当于有了一个字节点,这样就会自动拥有了了children 属性,我们到页面上看看。

1.2 props 校验

  • 对于组件来说,props 是外来的,无法保证组件使用者传入什么格式的数据 。
  • 如果传入的数据格式不对,可能会导致组件内部报错 。
  • 关键问题:组件的使用者不知道明确的错误原因。

看下面的例子。

我们可以看到了arr.map ,它调用的是map方法,那arr 就得是一个数组,但是大家看下面,它给我们传过来得是也给Number,Number根本就没有map方法,那这个时候就一定会报错。

面对这样得我们该如何解决呢? 这个时候我们就要进行 prop校验。我们来看看prop校验该怎么去做。

1、安装属性校验包:yarn add prop-types

2、导入prop-types 包,里面有各种各样的内置的校验规则。然后使用组件名.propTypes = {} 来给组件的props添加校验规则。

接下来我们就去看看控制台会不会报错,报的什么错?

我们直接看第一条报错,人家直接说了,我要一个数组,而你给我传了一个数字这明显不行呀。

接下来我们来继续了解一下这个props校验的其他规则。

  1. 常见类型:array、bool、func、number、object、string
  2. React元素类型:element
  3. 必填项:isRequired
  4. 特定的结构对象:shape({})

我们看看官方的文档。

Typechecking With PropTypes – React

接下来我们演示一下必填项吧。

你没有看错哈,这个东西就是这么简单,只是在后面点出来就行了。然后我们看看浏览器控制台。

这里就提醒了,这个地方是必填的,而你没有填。

那接下来我们来学习一个props 校验的默认值。

关于默认值的定义,我们的函数组件和这个类组件它们的定义方式是不一样的,我们先看看函数组件时如何定义的。

两种写法:

defaultProps:

函数参数默认值:

然后是类组件的默认值。

defaultProps:

静态属性定义:

2、组件的生命周期

组件的生命周期是指组件从被创建到挂载到页面中运行起来,再到组件不用时卸载的过程,注意,只有类组件才有生命周期(类组件 实例化 函数组件 不需要实例化)

大家可以看看这个网站,里面有组件的生命周期的流程图。React lifecycle methods diagram

2.1 生命周期 - 挂载阶段

钩子 函数

触发时机

作用

constructor

创建组件时,最先执行,初始化的时候只执行一次

1. 初始化state 2. 创建 Ref 3. 使用 bind 解决 this 指向问题等

render

每次组件渲染都会触发

渲染UI(注意: 不能在里面调用setState() )

componentDidMount

组件挂载(完成DOM渲染)后执行,初始化的时候执行一次

1. 发送网络请求 2.DOM操作

接下来进行一下代码演示。

我们看看它们的执行顺序是怎样的。

2.2 生命周期 - 更新阶段

钩子函数

触发时机

作用

render

每次组件渲染都会触发

渲染UI(与 挂载阶段 是同一个render)

componentDidUpdate

组件更新后(DOM渲染完毕)

DOM操作,可以获取到更新后的DOM内容,不要直接调用setState

代码演示:

效果:

2.3 生命周期 - 卸载阶段

钩子函数

触发时机

作用

componentWillUnmount

组件卸载(从页面中消失)

执行清理工作(比如:清理定时器等)

代码演示:

代码语言:javascript复制
import React from "react";


class Test extends React.Component {
    timer = null

    componentDidMount() {
        this.timer = setInterval(() => {
                console.log("定时器开启")
            }, 1000
        )
    }

    componentWillUnmount() {
        console.log("componentWillUnmount")
        // 清理定时器
        clearInterval(this.timer)
    }

    render() {
        return (
            <div>test</div>
        )
    }
}
class App extends React.Component {

    state = {
        count: 0,
        flag: true
    }
    clickHandler = () => {
        this.setState({
            count: this.state.count   1,
            flag: !this.state.flag
        })
    }
    render() {
        return (
            <div>
                {/* 通过一个数据状态的切换让Test组件进行销毁重建,就会发生组件卸载*/}
                {this.state.flag ? <Test/> : null}
                <button onClick={this.clickHandler}>{this.state.count}</button>
            </div>
        )
    }
}

export default App;

0 人点赞