精准渲染
2024年03月11日
一、缓存变量
1.1 useMemo
未使用 useMemo
缓存之前: App
中 num
的变化导致 App
组件重新渲染, App
函数重新执行, uniqueId
重新生成新的值。造成的现象就是, Component1
组件与 App
中的 num
状态毫无关系, 但是却因为 num
的变化而重新渲染了, 造成渲染浪费。
function getUniqueIdByNanoID(size = 10) {
let id = '';
let i = size;
const urlAlphabet =
'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict';
while (i--) {
id += urlAlphabet[(Math.random() * 64) | 0];
}
return id;
}
function getUniqueId(size) {
return getUniqueIdByNanoID(size);
}
function Component1(props){
const { uniqueId } = props;
console.log("Component1 Render", uniqueId);
return <div> Component 1 组件</div>
}
function App(){
const [num,setNum] = useState(0);
const uniqueId = getUniqueId();
console.log("App Render");
const handClick = ()=>{
setNum(num + 1);
}
return <div>
<h3>App 组件</h3>
<Component1 { uniqueId } />
</div>
}
使用 useMemo
缓存之后: App
中 num
的变化导致 App
组件重新渲染, App
函数重新执行。 而 uniqueId
通过 useMemo
包裹进行缓存, 不会生成新的值, 因此, App
中的 num
状态的变化不会导致 Component1
组件重新渲染。
function getUniqueIdByNanoID(size = 10) {
let id = '';
let i = size;
const urlAlphabet =
'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict';
while (i--) {
id += urlAlphabet[(Math.random() * 64) | 0];
}
return id;
}
function getUniqueId(size) {
return getUniqueIdByNanoID(size);
}
function Component1(props){
const { uniqueId } = props;
console.log("Component1 Render", uniqueId);
return <div> Component 1 组件</div>
}
function App(){
const [num,setNum] = useState(0);
const uniqueId = useMemo(()=> getUniqueId(), []);
console.log("App Render");
const handClick = ()=>{
setNum(num + 1);
}
return <div>
<h3>App 组件</h3>
<Component1 { uniqueId } />
</div>
}
二、缓存函数
2.1 useCallback
未使用 useCallback
缓存之前: App
中 num
的变化导致 App
组件重新渲染, App
函数重新执行, handleClick
重新生成新的函数。造成的现象就是, Component1
组件与 App
中的 num
状态毫无关系, 但是却因为 num
的变化而重新渲染了, 造成渲染浪费。
function Component1(props){
const { handleClick } = props;
console.log("Component1 Render");
return <div onClick={ handleClick }> Component 1 组件</div>
}
function App(){
const [num,setNum] = useState(0);
console.log("App Render");
const handleClick = ()=>{
setNum(num + 1);
}
return <div>
<h3>App 组件</h3>
<Component1 { handleClick } />
</div>
}
使用 useMemo
缓存之后: App
中 num
的变化导致 App
组件重新渲染, App
函数重新执行。 而 handleClick
通过 useCallback
包裹进行缓存, 不会生成新的函数, 因此, App
中的 num
状态的变化不会导致 Component1
组件重新渲染。
function Component1(props){
const { handleClick } = props;
console.log("Component1 Render");
return <div onClick={ handleClick }> Component 1 组件</div>
}
function App(){
const [num,setNum] = useState(0);
console.log("App Render");
const handleClick = useCallback(()=>{
setNum(num + 1);
}, [])
return <div>
<h3>App 组件</h3>
<Component1 { handleClick } />
</div>
}
三、缓存组件
3.1 memo
未使用 memo
缓存之前: App
中 num
的变化导致 App
组件重新渲染。造成的现象就是, Component1
组件与 App
中的 num
状态毫无关系, 但是却因为 num
的变化而重新渲染了, 造成渲染浪费。
function Component1(props){
const { num } = props;
console.log("Component1 Render", num);
return <div> Component 1 组件</div>
}
function App(){
const [num,setNum] = useState(0);
console.log("App Render");
const handleClick = ()=>{
setNum(num + 1);
}
return <div>
<h3 onClick={ handleClick }>App 组件</h3>
<Component1 { num: 0 } />
</div>
}