创建组件的两种方式
1. 函数式组件
react中的函数组件通常只考虑负责UI的渲染,没有自身的状态没有业务逻辑代码,没有生命周期,只是一个纯函数。下面这个函数组件就是一个纯函数,它的输出只由参数props决定,不受其他任何因素影响。(要想函数式组件有自己的状态以及生命周期方法,这里会有一个关于hooks的使用 hooks相关内容)
// 1.创建函数式组件
function Demo(params) {
console.log(this); //此处的this是undefind,因为babel编译的时候开启了严格模式
return <h2>我是用函数定义的组件(适用于【简单组件】的定义){params.title}</h2>
}
// 2.渲染组件到页面
ReactDOM.render(<Demo />, document.getElementById('app'))
/*
执行了ReactDOM.render(<Demo/>,....)
1.React解析组件标签,找到了Demo组件。
2.发现组件是使用函数来定义的,随后调用函数,将返回的虚拟dom转为真实的dom,随后呈现在页面上。
*/
所以在没有 hooks 之前,要想给需要的组件加状态,那就只能将组件重写为类组件,因为函数组件没有实例,没有生命周期。所以我们说在hook之前的函数组件和类组件最大的区别就是状态的有无。
纯函数组件的特点:
- 组件不会被实例化,整体渲染性能得到提升
- 组件不能访问this对象
- 组件无法访问生命周期的方法
- 无状态组件只能访问输入的props,无副作用
2. 类式组件
使用元素渲染或者是函数定义组件渲染来更新页面非常不方便,所以在一个 react 项目中我们应该使用类组件来渲染页面。使用类我们就可以使用它的一些特性,例如局部状态 state、生命周期钩子等,这大大方便了我们的开发。
下列代码就是创建类式组件的。
//1.创建类式组件
class MyComponent extends React.Component {
render() {
//render是放在那里的?--MyComponent的原型对象上,供实例使用。
//render中的this是谁?--MyComponent的实例对象《=》MyComponent组件实例对象。
console.log('render中的this', this);
return <h2>我是类定义的组件,(适用于【复杂组件】的定义)</h2>
}
}
// 2.渲染组件到页面
ReactDOM.render(<MyComponent />, document.getElementById('app'))
/*
执行了ReactDOM.render(<MyComponent/>,....)
1.React解析组件标签,找到了MyComponent组件。
2.发现组件是使用类来定义的,随后new出来实例,并通过该实例调用到原型上的render方法。
3.将render返回的虚拟DOM转为真实DOM,随后呈现在页面中。
*/
React类组件的生命周期
生命周期钩子函数(如图)
- 类组件有生命周期,函数组件没有生命周期的概念
- 类组件的生命周期有三个阶段, 五个钩子函数
挂载阶段的钩子
执行时机: 组件创建时(页面加载时)
执行顺序: constructor - - > render() - - > componentDidMount()
钩子函数 | 触发时机 | 作用 |
---|---|---|
constructor | 创建组件时,最先执行 | 1.初始化state 2.创建Ref等 |
render | 每次组件渲染都会触发 | 渲染UI |
componentDidMount | 组件挂载(完成DOM渲染)后 | 1.发送网络请求 2.DOM操作 |
更新阶段的钩子
更新阶段会执行的两个钩子: render() - - > componentDidUpdate()
三种操作可触发组件更新
- 调佣 setState 只要页面刷新(状态被改变),就会触发以上两个钩子
- 调用 forceUpdate() , 强制更新
补充: forceUpdate就是重新render。有些变量不在state上,但是你又想达到这个变量更新的时候,刷新render;或者state里的某个变量层次太深,更新的时候没有自动触发render。这些时候都可以手动调用forceUpdate自动触发render - 组件接收到新的props
说明: 以上三者任意一种发生, 组件就会进入更新阶段
钩子函数 | 触发时机 | 作用 |
---|---|---|
render | 每次组件渲染都会触发 | 渲染UI(与挂载阶段 是同一个render) |
componentDidUpdate | 组件更新(完成DOM渲染后) | DOM 操作 可以获取到更新后的DOM内容 |
如果有些事情是需要每次更新完毕后去做的, 就可以写componentDidUpdate中, 例如 : 数据本地存储
卸载阶段的钩子
钩子函数 | 触发时机 | 作用 |
---|---|---|
componenntWillUnmount | 组件卸载(从页面中消失) | 执行清理工作(例如: 清理定时器,移除事件) |