使用自定义挂钩防止组件重新渲染
Keep Component from Rerendering with Custom Hooks
我有一个自定义挂钩 useWindowSize
可以监听 window 大小的变化。一旦 window 大小低于某个阈值,一些文本应该会在 Menu
中消失。这是在另一个自定义钩子 useSmallWindowWidth
中实现的,它采用 useWindowSize
的返回值并检查它是否小于阈值。
但是,即使只有嵌套状态发生变化,我的组件也会在 window 大小发生变化时不断重新呈现。重新渲染菜单平均需要大约 50 毫秒,如果我想让其他组件也响应的话,这会加起来。
那么我怎样才能防止组件重新渲染呢?我通过在函数中传递 return prev.smallWindow === next.smallWindow;
来尝试 React.memo
,但它没有用。
我目前的尝试:
//this hook is taken from:
function useWindowSize() {
const [size, setSize] = useState([0, 0]);
useLayoutEffect(() => {
function updateSize() {
setSize([window.innerWidth, window.innerHeight]);
}
window.addEventListener('resize', updateSize);
updateSize();
return () => window.removeEventListener('resize', updateSize);
}, []);
return size;
}
function useSmallWindowWidth() {
const [width] = useWindowSize();
const smallWindowBreakpoint = 1024;
return width < smallWindowBreakpoint;
}
function Menu() {
const smallWindow = useSmallWindowWidth();
return (
<div>
<MenuItem>
<InformationIcon/>
{smallWindow && <span>Information</span>}
</MenuItem>
<MenuItem>
<MenuIcon/>
{smallWindow && <span>Menu</span>}
</MenuItem>
</div>
);
}
您可以尝试将所有 JSX 包装在一个 useMemo 中
function App() {
return useMemo(() => {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
</div>
);
}, []);
}
在 useMemo 的第二个参数的数组中放入什么变量应该使您的 jsx 重新呈现。如果设置了空数组(如示例中所示),则 jsx 永远不会重新呈现。
我有一个自定义挂钩 useWindowSize
可以监听 window 大小的变化。一旦 window 大小低于某个阈值,一些文本应该会在 Menu
中消失。这是在另一个自定义钩子 useSmallWindowWidth
中实现的,它采用 useWindowSize
的返回值并检查它是否小于阈值。
但是,即使只有嵌套状态发生变化,我的组件也会在 window 大小发生变化时不断重新呈现。重新渲染菜单平均需要大约 50 毫秒,如果我想让其他组件也响应的话,这会加起来。
那么我怎样才能防止组件重新渲染呢?我通过在函数中传递 return prev.smallWindow === next.smallWindow;
来尝试 React.memo
,但它没有用。
我目前的尝试:
//this hook is taken from:
function useWindowSize() {
const [size, setSize] = useState([0, 0]);
useLayoutEffect(() => {
function updateSize() {
setSize([window.innerWidth, window.innerHeight]);
}
window.addEventListener('resize', updateSize);
updateSize();
return () => window.removeEventListener('resize', updateSize);
}, []);
return size;
}
function useSmallWindowWidth() {
const [width] = useWindowSize();
const smallWindowBreakpoint = 1024;
return width < smallWindowBreakpoint;
}
function Menu() {
const smallWindow = useSmallWindowWidth();
return (
<div>
<MenuItem>
<InformationIcon/>
{smallWindow && <span>Information</span>}
</MenuItem>
<MenuItem>
<MenuIcon/>
{smallWindow && <span>Menu</span>}
</MenuItem>
</div>
);
}
您可以尝试将所有 JSX 包装在一个 useMemo 中
function App() {
return useMemo(() => {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
</div>
);
}, []);
}
在 useMemo 的第二个参数的数组中放入什么变量应该使您的 jsx 重新呈现。如果设置了空数组(如示例中所示),则 jsx 永远不会重新呈现。