本文正在参加「金石计划」
const [deferredValue] = useDeferredValue(value);
-
频繁更新组件进行节流
-
deferredValue 首次渲返回 value,再次渲染中首先返回原先数据,然后返回新的数据
-
value 应为原始数据或者是在渲染之外的对象
-
-
deferredValue 接收不同的数据时, 依赖它的渲染逻辑只会使用最新的数据进行渲染
-
<Suspense>
一块使用, 不会出现 fallback -
自身不会阻碍网络请求
-
useDeferredValue 不是固定的,渲染和事件更新都会影响
-
useDeferredValue 引发的 background re-rende 不会触发 Effect 执行,它会等到数据加载完UI更新以后
-
通常是组件内部使用
新数据加载时候展示旧数据
import { Suspense, useState } from 'react';
import SearchResults from './SearchResults.js';
export default function App() {
const [query, setQuery] = useState('');
const deferredQuery = useDeferredValue(query);
return (
<>
<label>
Search albums:
<input value={query} onChange={e => setQuery(e.target.value)} />
</label>
<Suspense fallback={<h2>Loading...</h2>}>
<SearchResults query={deferredQuery} />
</Suspense>
</>
);
}
添加效果
import { Suspense, useState, useDeferredValue } from 'react';
import SearchResults from './SearchResults.js';
export default function App() {
const [query, setQuery] = useState('');
const deferredQuery = useDeferredValue(query);
const isStale = query !== deferredQuery;
return (
<>
<label>
Search albums:
<input value={query} onChange={e => setQuery(e.target.value)} />
</label>
<Suspense fallback={<h2>Loading...</h2>}>
<div style={{
opacity: isStale ? 0.5 : 1,
transition: isStale ? 'opacity 0.2s 0.2s linear' : 'opacity 0s 0s linear'
}}>
<SearchResults query={deferredQuery} />
</div>
</Suspense>
</>
);
}
延迟部分 UI 重新渲染
function App() {
const [text, setText] = useState('');
const deferredText = useDeferredValue(text);
return (
<>
<input value={text} onChange={e => setText(e.target.value)} />
<SlowList text={deferredText} />
</>
);
}
const SlowList = memo(function SlowList({ text }) {
// ...
});
缓存节流子组件
- useDeferredValue只会节流你传给它的值
- 使用React.memo或者React.useMemo阻止子组件频繁更新
function Typeahead() {
const query = useSearchQuery('');
const deferredQuery = useDeferredValue(query);
// Memoizing tells React to only re-render when deferredQuery changes,
// not when query changes.
const suggestions = useMemo(() =>
<SearchSuggestions query={deferredQuery} />,
[deferredQuery]
);
return (
<>
<SearchInput query={query} />
<Suspense fallback="Loading results...">
{suggestions}
</Suspense>
</>
);
}