useEffect挂钩未在方向更改时触发

时间:2019-10-15 15:26:50

标签: javascript reactjs react-hooks

仅在移动横向模式下,我试图更改容器的高度。我在开发人员工具中玩耍以交换移动设备的方向,但是它仅在第一个渲染器上起作用。我是新来反应钩子的人,所以不确定我是否正确实施了钩子。

这个想法是,我正在横向测试一次,如果它在移动设备上,高度应该小于450px(这是我对if语句所做的检查)

有人可以指出我正确的方向吗?

谢谢!

const bikeImageHeight = () => {
    const windowViewportHeight = window.innerHeight;
    const isLandscape = window.orientation === 90 || window.orientation === -90;
    let bikeImgHeight = 0;

    if (windowViewportHeight <= 450 && isLandscape) {
      bikeImgHeight = windowViewportHeight - 50;
    }

    return bikeImgHeight;
  };

  useEffect(() => {
    bikeImageHeight();

    window.addEventListener("resize", bikeImageHeight);

    return () => {
      window.removeEventListener("resize", bikeImageHeight);
    };
  }, []);

3 个答案:

答案 0 :(得分:1)

useEffect钩子不会在方向改变时触发。它定义了在组件重新渲染时将触发的回调。然后的问题是,当屏幕方向改变时,如何触发重新渲染。当组件道具或状态发生更改时,将进行重新渲染。

让我们利用另一个related stackoverflow answer来构建一个useWindowDimensions挂钩。这样,我们就可以将窗口的大小作为组件状态来挂钩,以便任何更改都将导致重新渲染。

useWindowDimensions.js

import { useState, useEffect } from 'react';

function getWindowDimensions() {
  const { innerWidth: width, innerHeight: height } = window;
  return {
    width,
    height
  };
}

export default function useWindowDimensions() {
  const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions());

  useEffect(() => {
    function handleResize() {
      setWindowDimensions(getWindowDimensions());
    }

    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []);

  return windowDimensions;
}

然后可以在组件中使用该挂钩。像这样:

BikeImage.js

import React from 'react'
import useWindowDimensions from './useWindowDimensions'

export default () => {
  const windowDimensions = useWindowDimensions();

  // Define these helper functions as you like
  const width = getImageWidth(windowDimensions.width)
  const height = getImageHeight(windowDimensions.height)

  // AppImage is a component defined elsewhere which takes 
  // at least width, height and src props
  return <AppImage  width={width} height={height} src="..." .../>
}

答案 1 :(得分:0)

您需要触发重新渲染,这可以通过在bikeImageHeight内设置状态来完成。

  const [viewSize, setViewSize] = useState(0)


    const bikeImageHeight = () => {
        const windowViewportHeight = window.innerHeight;
        const isLandscape = window.orientation === 90 || window.orientation === -90;
        let bikeImgHeight = 0;

        if (windowViewportHeight <= 450 && isLandscape) {
          bikeImgHeight = windowViewportHeight - 50;
        }
        setViewSize(bikeImgHeight)
        return bikeImgHeight;
  };

在评论会话中,使用反跳的方法如下:

function debounce(func, wait, immediate) {
    var timeout;
    return function() {
        var context = this, args = arguments;
        var later = function() {
            timeout = null;
            if (!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
    };
};


const YourComponent = () => {

  const bikeImageHeight = () => {
    const windowViewportHeight = window.innerHeight;
    const isLandscape = window.orientation === 90 || window.orientation === -90;
    let bikeImgHeight = 0;

    if (windowViewportHeight <= 450 && isLandscape) {
      bikeImgHeight = windowViewportHeight - 50;
    }
    setViewSize(bikeImgHeight)
    return bikeImgHeight;
  };


  const debouncedBikeHeight = debounce(bikeImageHeight, 200)

  useEffect(() => {
    bikeImageHeight();

    window.addEventListener("resize", debouncedBikeHeight);

    return () => {
      window.removeEventListener("resize", debouncedBikeHeight);
    };
  }, []);

  return <div>some jsx</div>

}

示例防抖从此处获取:https://davidwalsh.name/javascript-debounce-function

答案 2 :(得分:0)

这是一个自定义挂钩,可在方向改变时触发

imputeMean()

希望这可以将您带向正确的方向。