❤️ Author: 老九
☕️ 个人博客:老九的CSDN博客
🙏 个人名言:不可控之事 乐观面对
😍 系列专栏:
文章目录
- setState原理
- setState异步更新
- SCU
- 不可变对象
- Ref
- Ref获取DOM
- Ref获取组件
- 非受控组件
- 受控组件
- 高阶组件(HOC)
- 作用一:进行函数增强功能
- 作用二:鉴权登录
- Portals
- React严格模式
- 封装轮播图组件
setState原理
- react没有做数据劫持,需要调用setState告诉react数据发生改变了,之后再调用render函数进行页面更新
- 我们修改了state之后,希望React根据最新的State来重新渲染界面,但是这种方式的修改React并不知道数据发生了变化,React并没有实现类似于Vue2中的Object.defineProperty或者Vue3中的Proxy的方式来监听数据的变化,我们必须通过setState来告知React数据已经发生了变化
setState异步更新
- setState的基本使用就是首先通过Object.assign将新数据替换掉原数据,之后在合适的位置重新调用render函数刷新页面
- 第二种写法是里面写一个箭头函数,返回一个对象,这样写有好处1:里面是一个回调函数,在里面可以写一些函数逻辑;好处2:当前的回调函数会将之前的state和props传递进来
- setState在React的事件处理中是一个异步调用,异步调用:并不会阻塞接下来代码的执行,操作并不会立刻完成,而是经过一些时间之后才会完成;如果希望数据更新之后立刻获取数据更新后的参数,可以在setState中传入第二个参数,callback函数
- 为什么setState设计为异步?
- setState设计为异步在GItHub的issue上个也有很多的讨论,Redux的作者也有对应的回复,我看完之后主要是由这两个问题
第一可以显著的提升性能,如果每次调用setState都进行一次更新,那么意味着render函数会被频繁调用,界面重新渲染,这样效率是很低的,最好的办法是获取到多个更新,之后进行批量更新
第二如果我们同步更新state,但是还没有执行render函数的时候,那么state的值和props里面的值就不能保持同步,在开发中会产生很多问题 - 那么setState一定是异步吗?
在React18之前,这样写是同步代码(或者直接写DOM原生的click操作),在React18之后,就算是setTimeout中setState也是异步操作,进行批量处理,如果要在18之后做同步处理,在React-dom包中,有一个flushSync函数,里面传一个回调函数写setState即可
SCU
- diff算法更新:同层结点之间相互比较,不会跨节点比较;不同类型的节点,产生不同的树结构,开发中可以通过key来指定哪些节点在不同的渲染下保持稳定
- 在react中,如果父组件的renden函数调用了,那么子组件的所有render函数也会调用,事实上很多组件没有必须要重新render,如果想让子组件中render不想更新,通过生命周期中shouldComponentUpdate方法
- 该方法有两个参数
- 如果当前组件是一个类组件,React提供了一个PureComponent;如果所有的类,我们都需要手动实现shouldComponentUpdate,那么会给我们开发者增加非常多的工作量,因此提供了一个pureComponenetUpdate
- 但是如果是一个函数组件,我们可以通过memo进行调用,通过判断props有没有改变来决定是否更新render函数
不可变对象
- 如果想在state中的对象添加一个元素,需要创建一个新的对象覆盖原对象,而不是直接修改原对象
Ref
Ref获取DOM
- 在React包中引入createRef,然后在constructor中创建ref,在元素上写一个ref属性,之后通过current获取值
Ref获取组件
- 通过forwardRef包裹函数,然后通过ref传递获取
非受控组件
- 通过ref获取值,表单中的元素没有写value值,与state数据无关
受控组件
- 一般input默认是非受控组件,只有我们可以动态修改值之后才是受控组件,如果input有默认值,我们通过输入框是无法修改值的,也就是所谓的非受控,当我们添加了onChange事件之后,可以修改值了,就变成受控组件了。类似于v-model
- 如果input类型是checkbox,值是checked,事件是onChange
- 如果是select的多选,需要这么写
高阶组件(HOC)
- 高阶组件是参数为组件,返回值为新组件的函数
- 利用高阶组件就是对某个组件进行了封装,包裹之后加了一些通用功能
作用一:进行函数增强功能
作用二:鉴权登录
Portals
- 某些情况下,我们希望渲染的内容独立于父组件,甚至独立于当前改在到DOM元素中(默认都是挂载到id为root的DOM元素上)
React严格模式
- StrictMode是一个组件,为其后代的元素触发额外的检查和警告
1.使用不安全生命周期会报警告
2.使用不安全的ref会报警告
3.检查意外的副作用
设置严格模式之后,这个组件的constructor会被调用两次,这是严格模式下故意进行的操作,让你来查看在这里写的一些逻辑代码被调用多次时,是否会产生一些副作用,在生产环境中,是不会被调用两次的
4.会检测过时的context API,早期Context是通过static属性声明Context对象,通过getChildContext返回Context对象等方式使用Context,目前这种方法已经不推荐使用了
封装轮播图组件
import { Component, ReactNode } from 'react'
type Props = {
imgs: string[],
buttons?: boolean,
indicators?: boolean,
autoplay?:number,
onChange?:(index:number)=>void,
}
type State = {
currentIndex:number,
}
class Slider extends Component<Props,State> {
static defaultProps = {
buttons: true,
indicators: true,
autoplay: 0,
onChange : () => {},
}
id: number | NodeJS.Timer = 0;
constructor(props : Props) {
super(props)
this.state = {
currentIndex: 0,
}
}
prev = () =>{
this.setState({
currentIndex: this.state.currentIndex - 1
}, () => {
this.props.onChange!(this.state.currentIndex)
})
if (this.state.currentIndex === 0) {
this.setState({
currentIndex: this.props.imgs.length-1
}, () => {
this.props.onChange!(this.state.currentIndex)
})
}
}
next = () => {
this.setState({
currentIndex: this.state.currentIndex + 1
}, () => {
this.props.onChange!(this.state.currentIndex)
})
if (this.state.currentIndex === this.props.imgs.length -1) {
this.setState({
currentIndex: 0
}, () => {
this.props.onChange!(this.state.currentIndex)
})
}
}
componentDidMount(): void {
if (this.props.autoplay! > 0) {
this.id = setInterval(() => {
this.next()
},this.props.autoplay)
}
}
componentWillUnmount(): void {
clearInterval(this.id)
}
render(): ReactNode {
return (
<div>
<img src={ this.props.imgs[this.state.currentIndex] } />
<button onClick={this.prev}><</button>
<button onClick={this.next}>></button>
<ul>
{
this.props.imgs.map((img,index) => {
return <li key={index} onClick={()=>this.setState({currentIndex:index})}>{index}</li>
})
}
</ul>
</div>
)
}
}
export default Slider
————————————————————————
♥♥♥码字不易,大家的支持就是我坚持下去的动力♥♥♥
版权声明:本文为CSDN博主「亚太地区百大最帅面孔第101名」的原创文章