所有的react问题可看下面链接总结
103个关于「React的高频面试」问题整理,适合面试或者全面学习 - 知乎
react生命周期
初始化阶段
construcstor
getDerivedStateFromProps(旧版本的getDefaultProps废弃)
render
componentDidMount
更新阶段
getDerivedStateFromProps
shouldComponentUpdate
render
getSnapShortBeforeUpdate(componentWillUpdate废弃)
compontDidUpdate
销毁阶段
compontWillUnmount
计划移除的生命周期
在16.4版本之后,被废弃的三个函数都是在render之前,因为fiber的出现,很可能因为高优先级任务的出现打断现有任务导致它们被执行多次
componentWillmount
componentWillupdate
componentWillReceviesProps
react hook介绍
react版本16.8之后才有hook函数
1、useState()
2、useEffect()
可以用来模拟声明周期,接收两个参数,第一个参数是函数,第二个参数是依赖值是个数组
当函数有返回值的时候,在组件被销毁时可以把上一次的事件监听或者延时器进行清除,以免造成内存泄漏
第二个依赖参数如果不写,每次组件更新都会调用
第二个参数是空数组,只有在第一次挂载时调用
第二个数组有值时,当值更新时会调用
3、useMemo()
4、useCallback()
5、useContext()
需要配合creatContext函数使用,const context = creatContext接收一个store数据,通过返回值的provide向后续组件传值,后续组件通过useContext(context)接收
6、useReduce()
解决复杂state的处理办法,usereduce接收三个参数,第一个参数是reduce函数,第二个参数是初始化数据,第三个是处理初始化数据的初始化函数,返回值是state和dispatch,dispach用来触发reduce函数
7、useRef()
8、memo
当组件被memo包括之后,如果父组件传过来的props没有更新,那组件就不会被重新渲染
需要注意的一点是memo对props的比较是浅比较,如果props中的属性是引用数据类型发生改变,那组件是不会更新的,解决这个的办法就是重新返回一个新的对象
memo也不是用的越多越好,对于一些经常被渲染且没必要时不用时时渲染
自定义hook
说说对react的理解,有哪些特性
react是一个用于构建用户界面的js库,提供了UI层面的解决方案
特性
1、单向数据流
2、组件化
3、jsx语法
4、虚拟dom
5、声明式编程
什么是函数组件?什么是类组件?
1、函数组件是用函数创建的组件,在react16.8版本之前,函数组件又叫做无状态组件
2、类组件是通过class类创建的组件
有什么区别?
1、在16.8之前,class组件成为有状态组件,因为他可以通过setState维护自己的状态,函数组件没有自己的状态,需要通过父组件传过来的props来展示UI
2、在16.8之后,函数组件通过hook有了自己的状态,建议统一使用函数组件
setState方法是如何工作的?setState是同步还是异步?
setState是如何工作的涉及到源码,后面再分析
setState是同步还是异步?
setState在react管理的事件机制中是异步的,因为如果有多个setState触发,react是会批量更新的,而在其他时候是立即更新的
1、在同步操作中,setState是异步的
// num初始值是0
handleSetState() {
console.log('---数量----', this.state.num)
this.setState({
num: this.state.num++
})
console.log('---数量----', this.state.num)
}
// 打印出的值是0 0
// 如果上述代码写在for循环中依次改变num的值,react实际上只会更新一次
2、在异步操作中,setState是同步的
// num初始值是0
handleSetState() {
setTimeout(()=> {
console.log('---数量----', this.state.num)
this.setState({
num: this.state.num++
})
console.log('---数量----', this.state.num)
},0)
}
// 打印出的值是0 1
// 如果上述代码写在for循环中依次改变num的值,react实际上会更新n次
什么是事件合成
React实现缓存的方式有哪些?他们有什么区别?
super和super(props)的区别
1、在react中,React.component组件基于ES6的类,所以在继承于React.component的组件需要super来继承父组件中的props
2、super的语法糖是:React.component.prototype.constauctor.call(this, props),将this绑定到子类上
3、在调用super的时候无论是否传props值,react都会把props绑定到类实例上,只有一个区别就是在构造函数内部,如果使用this.props是undefined,打印props不带this是一个对象
class Child extends React.component {
constructor(props) {
console.log('--------0000000', props) // {}
console.log('--------11111111', this.props) // undefined
}
}
react引入css的方式有哪些?
1. 可以行内引入
2. 可以使用import引入
3. 可以使用tailwindCss
react组件间的通信方式
1. 父传子组件通信用props
2. 子传父使用props+回调函数
3. 嵌套多层组件传递可以使用props、发布订阅模式、第三方库redux、context
发布订阅模式
// 可以使用pubsub库来实现发布订阅
// 订阅消息
// 有两个参数
// 第一个参数是订阅消息的名称
// 第二个参数是一个回调函数,回调函数接收两个参数
// 第一个参数是订阅消息的消息名, 可以使用简写方式为_,第二个参数是发布消息的数据
const token = pubsub.subscribe('name', (_, res) => {})
// 发布消息
pubsub.publish('name', '我是发送的数据')
// 取消订阅
// 接收的参数是订阅消息时的返回值
pubsub.unsubscribe(token)
context方式
import React from 'react';
const context = React.creatContext()
// 在app组件中通过context.Provider组件的value值进行传递
// app.js
function App(){
return (
<div>
<context .Provider value={windowProp}>
<component />
</context.Provider>
</div>
)
}
// 在组件中接收
this.context.属性
// 在函数组件中接收可以使用hook函数
const 接收的属性 = useContext(context)
react fiber
react hook的限制
react声明组件的方式
一、React.creatContext()
import React from 'react'
export default React.creatContext({
// 混入
mixins: [], // 在数组中写入混入的值
// 初始化state
getInitialState: function() {
return {
data: '在这里定义你的初始值吧'
}
},
// 给props定义初始值
getDefaultProps: function() {
return {
name: '我是默认值'
}
}
// 属性类型的定义
propsTypes: {
name: React.PropTypes.string
}
// 渲染函数
render: function() {
return <div>11111</div>
}
})
二、class
class DefaultCom extends React.component {
// 初始化
constructor(props) {}
}
三、函数组件
const DefaultFun = () => {
// 这里可以使用hook
return (
<div>这里是渲染的内容</div>
)
}
react插槽
react-Intl
react hook解决了什么问题
首先需要明确的是hook只能在函数组件中使用,在react16.8版本之后新增的hook,开始广泛使用函数组件,也就是解决了类组件的繁杂之处
1. 首先是状态难复用的问题
下面我分几点来阐述
一、类式组件的状态复用是通过高阶函数、render props、context,虽然这些也可以解决问题,但是显而易见这不是最佳的方案
二、hook诞生之后,函数组件也可以管理状态,可以通过hook来单独封装复用好的部分,函数组件也不需要复杂的生命周期等
2. 复杂组件难以理解
因为类式组件的状态难服用问题,很难将组件拆分成更小的部分,所以组件变得很冗杂,hook诞生之后就解决了这个问题
3. class类的额外学习
react的类式组件使用关键字class来写的,class是es6的新语法,而函数式组件是函数或者是箭头函数,几乎没有学习成本
react hook的使用限制有哪些
1、不要在循环、条件、嵌套函数中调用hook
2、在react的函数组件中调用hook