我正在尝试更改容器的高度,仅在移动横向模式下。我正在使用开发人员工具来交换移动设备的方向,但它仅适用于第一次渲染。我是反应钩子的新手,所以不确定我是否正确实现它。
这个想法是,我正在测试一旦在横向中,如果它在移动设备上,高度应该小于 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);
};
}, []);
useEffect
钩子预计不会在方向更改时触发。它定义了一个回调,该回调将在组件重新呈现时触发。那么问题是如何在屏幕方向更改时触发重新渲染。当组件属性或状态发生更改时,会发生重新渲染。
让我们利用另一个相关的 stackoverflow 答案来构建一个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;
}
然后,您可以在组件中使用该钩子。像这样:
自行车图片.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="..." .../>
}
这是一个在方向更改时触发的自定义钩子,
import React, {useState, useEffect} from 'react';
// Example usage
export default () => {
const orientation = useScreenOrientation();
return <p>{orientation}</p>;
}
function useScreenOrientation() {
const [orientation, setOrientation] = useState(window.screen.orientation.type);
useEffect(() => {
const handleOrientationChange= () => setOrientation(window.screen.orientation.type);
window.addEventListener('orientationchange', handleOrientationChange);
return () => window.removeEventListener('orientationchange', handleOrientationChange);
}, []);
return orientation;
}
希望这能带你到正确的方向。
您需要触发重新渲染,这可以通过在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