useDefferedValue的运用场景是什么?

useDefferedValue的运用场景是什么?
为什么我的这个并没有实现useDefferedValue的延迟效果(不影响input的更新)

import React, { memo, useDeferredValue, useEffect, useState } from 'react'

const SlowList = memo(function SlowList({ val }) {
    const startime = performance.now()
        while (performance.now() - startime < 500) {

        }
    return <>{val}</>
})

export default function DefferedValue() {
    const [state, setstate] = useState("");
    const defferedValue = useDeferredValue(state)
    return (
        <div>DefferedValue
            <input onChange={e => setstate(e.target.value)}
                value={state} />
            {/* <SlowList val={state}></SlowList> */}
            <SlowList val={defferedValue}></SlowList>
        </div>
    )
}

理论上不是应该每次输入,更新新的state的时候,slowList后台重新渲染,然后input的输入是不影响的,但是如果再次输入,就会触发slowList新的渲染,抛弃旧的渲染。就类似于渲染的防抖吗?


重新找了些资料,但是也没有解决问题。。。
从结果来看,没用useDefferedValue的:
image.png

slowList的渲染次数确实和输入的次数一样,而且,有大大的卡顿感觉

用了useDefferedValue的:
image.png
确实slowList的渲染次数只有两次,也就是中间打断了,但不知为什么,input还是有影响,有卡顿的感觉,看来目前还是只能使用防抖了,等成长了再回来看看。。

阅读 448
avatarAI BotBETA

useDeferredValue 是 React 中的一个 Hook,它的主要应用场景是优化性能,特别是在处理可能引发昂贵渲染的值时。这个 Hook 可以使得组件的渲染得以延迟,只有在组件下一次重新渲染时才会使用这个延迟的值。这可以帮助减少不必要的渲染,提高应用的性能。

然而,你的代码示例中并没有实现 useDeferredValue 的预期效果,原因主要有两点:

  1. Input 的值直接绑定到 state:在你的代码中,input 的 value 属性直接绑定到了 state。这意味着每次 state 更新时,input 都会重新渲染。由于 input 的渲染是直接的,它不会受到 useDeferredValue 的影响。
  2. useDeferredValue 的使用方式useDeferredValue 的主要目的是延迟值的更新,而不是阻止渲染。在你的代码中,defferedValue 是基于 state 的延迟值,但是 SlowList 组件的渲染仍然依赖于 defferedValue。因此,当 defferedValue 改变时,SlowList 仍然会重新渲染。

为了更好地理解 useDeferredValue 的工作原理,你可以考虑以下示例:

import React, { memo, useDeferredValue, useState } from 'react';

const SlowList = memo(function SlowList({ val }) {
    // 模拟一个昂贵的操作
    const startime = performance.now();
    while (performance.now() - startime < 500) {
    }
    return <>{val}</>;
});

export default function DefferedValue() {
    const [state, setstate] = useState("");
    const deferredState = useDeferredValue(state, { timeoutMs: 2000 });

    return (
        <div>
            <input onChange={e => setstate(e.target.value)} />
            <SlowList val={deferredState} />
        </div>
    );
}

在这个示例中,SlowList 的渲染是基于 deferredState 的,而 deferredStatestate 的延迟值。当你改变 input 的值时,state 会立即更新,但是由于 useDeferredValue 的存在,SlowList 的渲染会被延迟,直到 2 秒后才会使用新的 state 值进行渲染。这样,即使 state 更新,SlowList 的渲染也不会立即发生,从而实现了性能优化。

1 个回答
✓ 已被采纳

1、使用场景?
useDefferedValue 的作用在于延迟更新某个值的渲染(降低渲染的优先级),所以其运用场景是在用户输入频繁或处理大量数据时,避免过多的更新操作导致页面卡顿。通过将某个值包装在 useDeferredValue 中,React 会在 空闲时间段 更新该值,以保持页面的流畅性。其实在你的示例中已经实现了延迟更新的功能,即在 ShowList 渲染的过程中,优先更新 input 框的内容。

2、为什么会有卡顿的感觉?
示例中,当用户输入第一个字符,React 会优先响应 input 框。响应过后,React 会被认为进入 空闲时间段,此时进入 ShowList 渲染阶段。在 ShowList 渲染时会等待 500ms,此时 JS 线程被阻塞,React 无法进行响应,这就是你为什么会觉得卡顿。

3、为什么 JS 线程被阻塞 React 就无法响应?React 不是号称实现了并发模式吗?
因为 JS 是单线程的,React 的并发是基于 时间分片(React Fiber)的假并发。也就是当 JS 线程被阻塞时,React 就被卡死了,并没有办法根据优先级进行优先渲染。

希望我的回答对你的问题有所帮助~

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题