Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/reporting-services/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 事件侦听器中的多个状态更改,如何不批处理DOM更新?_Reactjs - Fatal编程技术网

Reactjs 事件侦听器中的多个状态更改,如何不批处理DOM更新?

Reactjs 事件侦听器中的多个状态更改,如何不批处理DOM更新?,reactjs,Reactjs,我正在构建一个组件来测试不同算法的性能。算法返回运行时使用的ms,这是我想要显示的。“fastAlgorithm”大约需要半秒,“slowAlgorithm”大约需要5秒 我的问题是,在两种算法完成之前,用户界面不会重新呈现结果。我想在快速算法完成后立即显示结果,在慢速算法完成后显示结果 我已经读过关于如何在重新渲染之前进行批处理更新的内容,但是有什么方法可以改变这种行为吗?或者是否有更好的方法来组织我的组件以实现我的目标 我用的是react 16.13.1 以下是我的组件: import {

我正在构建一个组件来测试不同算法的性能。算法返回运行时使用的ms,这是我想要显示的。“fastAlgorithm”大约需要半秒,“slowAlgorithm”大约需要5秒

我的问题是,在两种算法完成之前,用户界面不会重新呈现结果。我想在快速算法完成后立即显示结果,在慢速算法完成后显示结果

我已经读过关于如何在重新渲染之前进行批处理更新的内容,但是有什么方法可以改变这种行为吗?或者是否有更好的方法来组织我的组件以实现我的目标

我用的是react 16.13.1

以下是我的组件:

import { useState } from 'react'
import { fastAlgorithm, slowAlgorithm } from '../utils/algorithms'

const PerformanceTest = () => {

  const [slowResult, setSlowResult] = useState(false)
  const [fastResult, setFastResult] = useState(false)

  const testPerformance = async () => {
    fastAlgorithm().then(result => {
      setFastResult(result)
    })
    slowAlgorithm().then(result => {
      setSlowResult(result)
    })
  }

  return (
    <div>
      <button onClick={testPerformance}>Run test!</button>
      <div>{fastResult}</div>
      <div>{slowResult}</div>
    </div>
  )
}

export default PerformanceTest
还有:

const testPerformance = async () => {
  fastAlgorithm().then(result => {
    ReactDOM.flushSync(() =>
      setFastResult(result)
    )
  })
  slowAlgorithm().then(result => {
    ReactDOM.flushSync(() =>
      setSlowResult(result)
    )
  })
}
我还尝试重新构造算法,使其不使用承诺,并尝试了以下方法,但没有成功:

 const testPerformance = () => {
   setFastResult(fastAlgorithm())
   setSlowResult(slowAlgorithm())
 }
编辑

正如Sujoy Saha在下面的评论中所建议的那样,我使用setTimeout()将我的算法替换为简单的算法,一切正常。首先显示“快”,然后两秒钟后显示“慢”

但是,如果我执行下面的代码,它将不起作用。当较慢的功能完成时,“快”和“慢”都会显示。。。是否有人确切知道React中的批处理渲染何时/如何发生,以及如何避免

export const slowAlgorithm  = () => {
  return new Promise((resolve, reject) => {
    const array = []
    for(let i = 0; i < 9000; i++) {
      for(let y = 0; y < 9000; y++) {
        array.push(y);
      }
    }
    resolve('slow')
  })
}
export const slowAlgorithm=()=>{
返回新承诺((解决、拒绝)=>{
常量数组=[]
对于(设i=0;i<9000;i++){
对于(设y=0;y<9000;y++){
阵列推送(y);
}
}
解决(“慢”)
})
}

您的初始性能测试组件是正确的。组件将针对每个状态更改重新渲染。我认为问题在于你们的算法。请让我们知道你是如何回到那里的。 下面的代码片段供您参考

export const fastAlgorithm  = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('fast')
    }, 1000)
  })
}

export const slowAlgorithm  = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('slow')
    }, 3000)
  })
}

您是否在主线程上同步运行算法?如果是这样,这可能就是阻止React重新渲染的原因。您可能需要将它们移动到

以下内容大致基于,减去所有兼容性内容(假设您不需要IE支持):

//注意,`args`必须都是JSON可序列化的,
//由于我们创建工作字符串的方式。
//如果没有参数,也可以(`args`则为[])
const asyncify=fn=>(…args)=>{
常数workerStr=`
常量fn=${fn.toString()}
const start=new Date()。valueOf()
self.onmessage=()=>{
const returnVal=fn(${args.map(JSON.stringify.join)(“,”})
const executionTimeMs=new Date().valueOf()-start
self.postMessage({returnVal,executionTimeMs})
}
`
constblob=newblob([workerStr],{type:“application/javascript”})
常量工作者=新工作者(URL.createObjectURL(blob))
持续承诺=新承诺((解决、拒绝)=>{
worker.onmessage=(结果)=>{
解决(结果)
worker.terminate()
}
worker.onerror=(err)=>{
拒绝(错误)
worker.terminate()
}
})
worker.postMessage(null)
//以防我们以后需要它进行清理
promise.abort=worker.terminate.bind(worker)
回报承诺
}
常量slowAlgorithm=(外部写入,内部迭代)=>{
常量数组=[]
for(设i=0;i
document.write(`${JSON.stringify(x,null,2)}`)
slowAlgorithmAsync(9000,9000)
。然后({data})=>渲染(数据))
slowAlgorithmAsync(100100)

。然后({data}=>render(data))
谢谢!我用你的代码替换了我的算法,一切正常。首先显示“快”,然后两秒钟后显示“慢”。但是,如果我删除setTimeout()函数,而执行类似于下面的操作,它将不起作用。当较慢的功能完成时,“快”和“慢”都会显示<代码>导出常量slowAlgorithm=()=>{return new Promise((resolve,reject)=>{const array=[]for(let i=0;i<9000;i++){for(let y=0;y<9000;y++){array.push(y);}}resolve('slow')}
export const fastAlgorithm  = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('fast')
    }, 1000)
  })
}

export const slowAlgorithm  = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('slow')
    }, 3000)
  })
}