Не допускайте повторной рендеринга компонента с помощью пользовательских хуков
У меня есть кастомный крючок useWindowSize
который слушает изменения размера окна. Как только размер окна станет ниже определенного порога, некоторый текст должен исчезнуть вMenu
. Это реализовано в другом кастомном хукеuseSmallWindowWidth
который принимает возвращаемое значение useWindowSize
и проверяет, меньше ли оно порогового значения.
Однако, несмотря на то, что изменяется только вложенное состояние, мой компонент постоянно перерисовывается при изменении размера окна. Повторный рендеринг меню занимает в среднем около 50 мсек, что складывается, если я хочу, чтобы другие компоненты также реагировали.
Итак, как я могу предотвратить повторную отрисовку компонента? Я попыталсяReact.memo
мимо return prev.smallWindow === next.smallWindow;
внутри функции, но это не сработало.
Моя попытка до сих пор:
//this hook is taken from: https://stackru.com/questions/19014250/rerender-view-on-browser-resize-with-react
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>
);
}
1 ответ
Вы можете попробовать обернуть весь свой 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 rerender. Если установлен пустой массив (как в примере), jsx никогда не перерисовывается.