📔
饥人谷前端体系课程笔记
黑马程序员笔记前端面试押题前端精进
  • 课程大纲
  • Git入门
    • 3. 软件安装详解
    • 4. Mac环境搭建
    • 5. 命令行入门
    • 6. 本地仓库
    • 7. Git远程仓库-GitHub
  • HTML全解
    • 8. HTML概览
    • 9. HTML标签
    • 10. HTML重难点
    • 11. HTML实践 & 手机调试
  • CSS全解
    • 12. CSS基础
    • 13. CSS布局(上)
    • 14. CSS布局(下)
    • 15. CSS定位
    • 16. CSS动画
  • HTTP全解
    • 17. URL 是什么
    • 18. 请求和响应 & Node.js Server
  • JS全解
    • 19. JavaScript概览
    • 20. 内存图与JS世界(精品课)
    • 21. Canvas 实践—画图板
    • 22. JS语法
    • 23. JS数据类型
    • 24. JS 对象
    • 25. JS 对象分类
    • 26. JS 数组
    • 27. JS 函数
    • 28. JS 实战,会动的代码
    • 29. JS运算符
    • 30. JS总结
  • JS编程接口
    • 31. DOM编程
    • 32. 手写DOM库
    • 33. JQuery中的设计模式(上)
    • 34. JQuery中的设计模式(下)
    • 35. DOM事件与事件委托
  • 项目 前端导航站点
    • 前端导航项目笔记
  • 前后分离
    • 40. AJAX的原理
    • 41. 异步与Promise
    • 42. 跨域、CORS、JSONP
    • 43. 静态服务器
    • 44. AJAX实战:Cookie、Session
  • JS进阶MVC
    • 48. MVC(上)
    • 49. MVC(中)
    • 50. MVC(下)
  • 项目构建
    • 51. Webpack(上)
    • 52. Webpack(下)
  • 算法与数据结构
    • 62. 伪代码与流程图
  • React全解
    • 75. React起手式
    • 76. React类组件和函数组件
    • 77. Class组件详解
    • 78. 函数组件
    • 79. Hooks原理解析
    • 80. Hooks各个击破
    • 81. 精通Redux
  • Node.js
    • 84. Node.js技术架构
    • 85. 文件模块
    • 86. 单元测试之文件模块
    • 87. 调试 Node.js 程序
    • 88. 静态服务器
    • 89. 命令行翻译工具
    • 90. 操作数据库
    • 91. 数据库基础知识
    • 92. Stream 流
    • 93. child_process
    • 94. 总结
  • TypeScript
    • 112. 基础
    • 113. 泛型
  • Next.js全解
    • Next.js 上
    • Next.js 下
  • ES6精讲
    • Promise,async/await
  • 大屏可视化笔记
    • 大屏可视化项目
  • SCSS全解
    • SCSS全解
  • 拓展
    • 一次性弄懂性能优化
    • Web性能优化
由 GitBook 提供支持
在本页
  • 77. Class组件详解
  • 英语小课堂
  • 两种创建class组件的方式
  • ES6的class方式好
  • 浏览器不支持ES6怎么办
  • props
  • 初始化
  • 效果
  • 读取
  • 改props的值(一个地址)
  • 改props的属性
  • 原则
  • 相关钩子
  • componentWillReceiveProps钩子
  • 该钩子已经被弃用
  • Props的作用(面试可能会问)
  • state
  • 初始化State
  • 读写State
  • 读用this.state
  • 写用this.setState(???,fn)
  • 写时会shallow merge
  • 生命周期
  • 类比如下代码
  • 同理
  • 函数列表
  • 函数列表 - 必会
  • constructor
  • 用途
  • 生命周期之shouldComponentUpdate
  • 用途
  • 面试常问
  • 生命周期之render
  • 用途
  • 技巧
  • 生命周期之componentDidMount
  • 用途
  • 参数
  • 生命周期之componentDidUpdate
  • 用途
  • 参数
  • 生命周期之componentWillUnmount
  • 用途
  • 举例
  • 总结
  • 分阶段看钩子执行顺序
  • 函数列表 - 必会

这有帮助吗?

  1. React全解

77. Class组件详解

Class

77. Class组件详解

英语小课堂

derived 导出的,衍生的,派生的

render渲染

super class 超类,父类

property属性

state状态

mount挂载

两种创建class组件的方式

ES5方式(过时)

import React from 'react'

const A = React.createClass({
  render(){
    return (
    	<div>hi</div>
    )
  }
})
export default A
//由于ES5不支持class,才会有这种方式

ES6方式

import React from 'react';
class B extends React.Component{
 constructor(props){
  super(props);
 }
 render(){
   return (//圆括号约定俗成不要删掉
   	<div>hi</div>
   )
 }
}
export default B;
//extends, constructor, super强行记忆,别问为什么
 constructor(props){
  super(props);
 }
 这个可以删掉

哪种好?

ES6的class方式好

以后我们只用这种方式创建类组件

浏览器不支持ES6怎么办

你公司怎么还在搞IE8,肯定是个破公司,跳槽吧

用webpack+babel将ES6翻译成ES5即可

props

外部数据

传入props给B组件

class Parent extends React.Component{
  constructor(props){
  	super(props)
  	this.state = {name:'frank'}
  }
  onClick = () =>{}
  render(){
  	return <B name = {this.state.name}
    						onClick={this.onClick}>hi</B>
  }
  }
  //外部数据被包装为一个对象
  //{name: 'frank', onClick:..., children:'hi'}
  //此处的onClick是一个回调
  
	
}

初始化

class B extends React.Component{
	constructor(props){
		super(props);
	}
	render(){}
}

要么不初始化,即不写constructor

要么初始化,且必须写全套(不写super直接报错)

效果

这么做了之后,this.props就是外部数据对象的地址了

读取

class B extends React.Component{
	constructor(props){
		super(props);
	}
	render(){
		return <div onClick={this.props.onClick}>
		{this.props.name}
		<div>
		{this.props.children}
		</div>
	}
}
//通过this.props.xxx读取

读props会了,写props呢

不准写(入)props!!!永远不要尝试对props改写

改props的值(一个地址)

this.props = {/*另一个对象*/}

不要写这样的代码,没有意义

理由:既然是外部数据,就应该由外部更新

改props的属性

this.props.xxx = 'hi'

不要写这样的代码,没有意义

理由:既然是外部数据,就不应该从内部改值

原则

应该由数据的主人对数据进行更改

相关钩子

componentWillReceiveProps钩子

当组件接受新的props时,会触发此钩子

啥是钩子?黑话,你就将其翻译成“特殊函数”即可。

该钩子已经被弃用

更名为UNSAFE_componentWillReceiveProps

总而言之,不要使用这个钩子

方方为什么会教这个?不推荐使用为什么还要教?教是为了让你能看懂就代码,这钩子以前是推荐使用的。

Props的作用(面试可能会问)

  • 接受外部数据

只能读不能写

外部数据由父组件传递

  • 接受外部函数

在恰当的时机,调用该函数

该函数一般是父组件的函数

state

初始化State

class B extends React.Component {
	constructor(props){
		super(props);
		this.state = {
			user: {name: 'frank',age:18}
		}
	}
	render(){/*... */}
}

读写State

读用this.state

this.state.xxx.yyy.zzz

写用this.setState(???,fn)

this.setState(newState,fn)

注意setState不会立刻改变this.state, 会在当前代码运行完后,再去更新this.state,从而触发UI更新

this.setState((state,props) => newState,fn)

这种方式的state反而更易于理解

fn会在写入成功后执行

写时会shallow merge

setState会自动将新state与旧state进行一级合并

生命周期

类比如下代码

//这是div的create/construct过程
let div = document.createElement('div')
//这是初始化state
div.textContent = 'hi'
//这是div的mount过程
document.body.appendChild(div)
//这是div的update过程
div.textContent = 'hi2'
//这是div的unmount过程
div.remove()

同理

React组件也有这些过程,我们称之为生命周期

函数列表

  • constructor()

  • static getDerivedStateFromProps()

  • shouldComponentUpdate()

  • render()

  • getSnapshotBeforeUpdate()

  • componentDidMount()

  • componentDidUpdate()

  • componentWillUnmount()

  • static getDerivedStateFromError()

  • componentDidCatch()

函数列表 - 必会

  • constructor() 在这里初始化state

  • shouldComponentUpdate() return false阻止更新

  • **render()**创建虚拟DOM

  • **componentDidMount()**组件已出现在页面

  • **componentDidUpdate()**组件已更新

  • **componentWillUnmount()**组件将死

constructor

用途

  • 初始化props

  • 初始化state,但此时不能调用setState

  • 用来写bind this

constructor(){
	/*其他代码略*/
	this.onClick = this.onClick.bind(this)
}
//可以用新语法代替
onClick = ()=>{}
constructor(){/* 其他代码略 */}
可不写
  • 可不写

生命周期之shouldComponentUpdate

用途

  • 返回true表示不阻止UI更新

  • 返回false表示阻止UI更新

  • 示例见下页

面试常问

问:shouldComponentUpdate有什么用?

答:它允许我们手动判断是否要进行组件更新,我们可以根据应用场景灵活地设置返回值,以避免不必要的更新

class App extends React.Component{
  constructor(props){
    super(props);
    this.state = {
      n : 1
    };
  }
  onClick = () => {
    this.setState(state =>({n: state.n + 1}));
    this.setState(state =>({n: state.n - 1}));
  };
  //react每次返回的是一个新的对象,因此,即使最后n的值是一样的,但是上面的{n:1}和{n:1}是不同的对象
  shouldComponentUpdate(newProps, newState){
    if(newState.n === this.state.n){
      //shouldComponentUpdate(){
      //if(argument[1].n === this.state.n)也可以
      return false
    }else{
      return true
    }
  }
  render(){
    console.log('render了一次')
    return (
    	<div>
      	{this.state.n}
        <button onClick={this.onClick}>+1-1</button>
      </div>
    );
  }
}

启发:

其实可以将newState和this.state的每个属性都对比一下,如果全部相等,就不更新如果有一个不等,就更新

再启发:

为什么React不内置此功能?React确实内置了,这个功能叫做React.PureComponent,可以代替React.Component

如果面试官问PureComponent是干什么的?怎么回答?

答:PureComponent 会在 render 之前对比新 state 和旧 state 的每一个 key,以及新 props 和旧 props 的每一个 key。 如果所有 key 的值全都一样,就不会 render;如果有任何一个 key 的值不同,就会 render。

质疑:

为什么要用新的对象?为什么我们不直接在this.state身上改呢?

这触及到编程哲学了,以后聊

生命周期之render

用途

  • 展示视图 return (<div>...</div>)

  • 只能有一个根元素

  • 如果有两个根元素,就要用<React.Fragment>包起

  • <React.Fragment />可以缩写成<></>

技巧

  • render里面可以写if..else

  • render里面可以写?:表达式

  • render里面不能直接写for循环,需要用数组

  • render里面可以写array.map(循环)

所有的循环(array.map)都要加个key

<span key = {n}></span
Warning: Each child in a list should have a unique "key" prop. 

生命周期之componentDidMount

组件已经挂载了。

用途

  • 在元素插入页面后执行代码,这些代码依赖DOM

  • 比如你想获取div的高度,就最好在这里写

  • 此处可以发起加载数据的AJAX请求(官方推荐)

  • 首次渲染会执行此钩子

参数

看文档

生命周期之componentDidUpdate

用途

  • 在视图更新后执行代码

  • 此处也可以发起AJAX请求,用于更新数据(看文档)

  • 首次渲染不会执行此钩子

  • 在此处setState可能会引起无限循环,除非放在if里

  • 若shouldComponentUpdate返回false,则不触发此钩子

参数

看文档

componentDidUpdate(prevProps, prevState, snapshot)

生命周期之componentWillUnmount

用途

组件将要被移出页面然后被销毁时执行代码

unmount过的组件不会再次mount

举例

如果你在componentDidMount里面监听了window scroll,那么你就要在componentWillUnmount里面取消监听。

如果你在componentDidMount里面创建了Timer,那么你就要在componentDidMount里面取消Timer。

如果你在componentDidMount里面创建了AJAX请求,那么你就要componentDidMount里面取消请求。

否则你就是菜逼

原则:谁污染谁治理

总结

分阶段看钩子执行顺序

函数列表 - 必会

  • constructor() 在这里初始化state

  • shouldComponentUpdate() return false阻止更新

  • **render()**创建虚拟DOM

  • **componentDidMount()**组件已出现在页面

  • **componentDidUpdate()**组件已更新

  • **componentWillUnmount()**组件将死

不要忘了return true

希望你背下常用生命周期的拼写和用途

纠错:React.PureComponent

视频中说

PureComponent 会在 render 之前对比新 state 和旧 state 的每一个 key。

这句话错在不够完整,完整的说法是

PureComponent 会在 render 之前对比新 state 和旧 state 的每一个 key,以及新 props 和旧 props 的每一个 key。 如果所有 key 的值全都一样,就不会 render;如果有任何一个 key 的值不同,就会 render。

上一页76. React类组件和函数组件下一页78. 函数组件

最后更新于3年前

这有帮助吗?

https://codesandbox.io/s/thirsty-meitner-zlg0v6?file=/src/App.js
https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/