使用自定义挂钩阻止组件渲染

时间:2020-09-02 11:17:01

标签: reactjs react-hooks react-memo

我有一个自定义钩子useWindowSize,用于监听窗口大小的变化。窗口大小低于某个阈值后,Menu中的某些文本应会消失。这是在另一个自定义钩子useSmallWindowWidth中实现的,该钩子接受返回的值useWindowSize并检查其是否小于阈值。

但是,即使仅嵌套状态发生了变化,当窗口大小发生变化时,我的组件也会不断地重新渲染。重新渲染菜单平均需要大约50毫秒,如果我也想使其他组件也具有响应能力,那么这总计会增加。

那么我该如何避免重新渲染组件?我通过在函数中传递React.memo来尝试return prev.smallWindow === next.smallWindow;,但是没有用。

到目前为止,我的尝试:

//this hook is taken from: https://stackoverflow.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 个答案:

答案 0 :(得分:0)

您可以尝试将所有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永不放弃。