unstable_batchedUpdates(react手动批量更新)的使用场景

1,376 阅读1分钟

首先了解下批量更新,在以下两种情况下,只会渲染一次

class有状态组件中的this.setStatehooks中useState,两种方法已经做了批量更新的处理

class组件

class index extends React.Component{
    constructor(prop){
        super(prop)
        this.state = {
            a:1,
            b:2,
            c:3,
        }
    }
    handerClick=()=>{
        const { a,b,c } :any = this.state
        this.setState({ a:a+1 })
        this.setState({ b:b+1 })
        this.setState({ c:c+1 })
    }
    render= () => <div onClick={this.handerClick} />
}

hook中

无状态组件中
    const  [ a , setA ] = useState(1)
    const  [ b , setB ] = useState({})
    const  [ c , setC ] = useState(1)
    const handerClick = () => {
        setB( { ...b } ) 
        setC( c+1 ) 
        setA( a+1 )
    }

但是 批量更新在某些情况下会失效,造成多次渲染 ,例如setTimeout,Promise.then(fn), fetch回调,xhr网络回调等,如下例子会渲染3次

handerClick=()=>{
    setTimeout(() => {
        this.setState({ a:a+1 })
        this.setState({ b:b+1 })
        this.setState({ c:c+1 })
    }, 0)
}

 const handerClick = () => {
    Promise.resolve().then(()=>{
    setB( { ...b } ) 
    setC( c+1 ) 
    setA( a+1 )
    })
}

为了避免此类情况发生,我们需要引入unstable_batchedUpdates 进行手动合并,如下

handerClick=()=>{
    setTimeout(() => {
        unstable_batchedUpdates(()=>{
            this.setState({ a:a+1 })
            this.setState({ b:b+1 })
            this.setState({ c:c+1 })
        })
    }, 0)
}

 const handerClick = () => {
    Promise.resolve().then(()=>{
        unstable_batchedUpdates(()=>{
            setB( { ...b } ) 
            setC( c+1 ) 
            setA( a+1 )
        })
    })
}