目录
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校验的其他规则。
- 常见类型:array、bool、func、number、object、string
- React元素类型:element
- 必填项:isRequired
- 特定的结构对象: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;