- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
很抱歉问了这么长的问题,但我需要做一个介绍以使其更清楚。
我需要一些代码来在我的 Headers 组件之间切换 <HeaderDesktop>
和 <MobileHeader>
.
起初我使用 CSS 媒体查询通过 display: block | none;
在它们之间切换.这不太理想,因为两个组件将同时呈现,这是低效的,并且可能会给隐藏元素上的广告显示带来问题。
SO 上有人建议我可以使用 window.innerWidth
并基于此使用 React 确定要渲染的组件。那确实好多了。现在一次只渲染 1 个组件。这就是我所做的:
// INSIDE HEADER COMPONENT
return(
<HeaderWrapper>
{window.innerWidth < 1200 ?
<HeaderMobile/>
: <HeaderDesktop/>
}
</HeaderWrapper>
);
但我需要一种方法来处理调整大小事件。所以我做了:
// INSIDE HEADER COMPONENT
const [windowSize, setWindowSize] = useState(window.innerWidth);
function handleResize() {
setWindowSize(window.innerWidth);
}
return(
<HeaderWrapper>
{windowSize < 1200 ?
<HeaderMobile/>
: <HeaderDesktop/>
}
</HeaderWrapper>
);
不错!这行得通,但现在每次调整大小时,我的组件每秒渲染 1 万亿次。这对性能没有好处。
所以我做了我的研究并发现了 lodash throttle
和 debounce
方法。两者都可以减少和控制处理的事件数量,即使随后触发了数百个事件。
https://css-tricks.com/debouncing-throttling-explained-examples/
但我不喜欢将整个库添加到我的依赖项列表中只是为了使用这样一个简单的功能,所以我最终创建了以下效果 Hook 来模仿 throttle
我的功能 resize
事件处理程序。
// INSIDE HEADER COMPONENT
// Ref to store if there's a resize in progress
const resizeInProgress = useRef(false);
// State to store window size
const [windowSize, setWindowSize] = useState(window.innerWidth);
useEffect(() => {
// This function trigger the resize event handler
// And updates the ref saying that there's a resize in progress
// If theres a resize in progress, it doesn't do anything
function handleResize() {
if (resizeInProgress.current === true) {
return;
}
resizeInProgress.current = true;
throttled_updateWindowSize();
}
// This function sets a timeout to update the state with the
// new window size and when it executes, it resets the
// resizeInProgress ref to false. You can execute what's the interval
// You want to handle your resize events, in this case is 1000ms
function throttled_updateWindowSize() {
setTimeout(() => {
console.log("I will be updated!");
console.log(window.innerWidth);
setWindowSize(window.innerWidth);
resizeInProgress.current = false;
}, 1000);
}
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);
您可以在以下沙盒中看到这一点:
https://codesandbox.io/s/v3o0nmvvl0
问题 1
关于如何改进调整大小事件处理程序的节流版本的代码,您能给我一些建议吗?
问题 2
我猜我会在其他组件中需要该功能。我怎样才能使它易于重用?我可以将其设为自定义 Hook 吗?我从来没有创建过一个,所以我仍然在如何推理它们以及创建它们的正确方法方面遇到一些麻烦。你能帮我把它放到 Custom Hook 中吗?
或者为此创建一个高阶组件会更好吗?
最佳答案
这不是我用钩子(Hook)做的事情。您可以让它作为一个 Hook 工作,但您将自己限制在仅在组件内部进行节流,而节流是一个比这更有用的实用功能,而 Hook 不会让它变得更容易或让您做任何额外的事情。
如果您不想导入所有的 lodash,这是可以理解的,但您可以自己实现类似的东西。 Lodash 的 throttle 是一个高阶函数:你将它传递给一个函数,它会返回一个新函数,它只会在自上次执行以来经过了适当的时间后才执行。可以像这样复制执行此操作的代码(没有像 lodash 那样多的选项和安全检查):
const throttle = (func, delay) => {
let inProgress = false;
return (...args) => {
if (inProgress) {
return;
}
inProgress = true;
setTimeout(() => {
func(...args); // Consider moving this line before the set timeout if you want the very first one to be immediate
inProgress = false;
}, delay);
}
}
像这样使用:
useEffect(() => {
const handleResize = throttle(() => {
setWindowSize(window.innerWidth);
}, 1000);
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);
关于javascript - 节流函数(受 lodash 启发)仅使用 React Hook (使用 Sandbox)来处理调整大小事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55973826/
我每天运行命令将新记录插入 BigQuery 表,并想记录每天插入的记录数。 我创建了一个 QueryJob包含 SELECT 查询和 destination 表的对象。我将 write_dispos
当您登录受密码保护的页面时,WordPress 会设置一个类似于 wp-postpass_hash 的 cookie。 这个 cookie 似乎永远存在。我希望能够为用户提供“注销”链接。如果我不知道
我正在用 C++ 设计一个公共(public) API,我相信我想保留 C++ 属性函数样式约定,它们看起来像 int& Value() 和 const int& Value() const 而不是按
我正在构建一个使用 jQuery 图片库的网站。你可以看一个例子 here . 出于某种原因,当画廊更改图像时,或者当您手动更改图像时,页面高度似乎因为需要更好的词而“闪烁”。新图像似乎增加了页面高度
我正在尝试使用 CSS3 实现一个简单的 3D 照片库。它在 IE10+ 浏览器上运行良好,但在最新版本的 chrome 上有一个小错误,即单击时按钮消失。谁能告诉我如何解决这个问题?提前谢谢你。 w
我想知道为什么其中一些程序会抛出段错误,而另一些则不会。 这个程序抛出一个段错误: #include int main(){ int ar[2096263]; printf("asd
今天我移植了我的旧内存基准测试 从 Borland C++ builder 5.0 到 BDS2006 Turbo C++,发现奇怪的事情。 BCB5 的 exe 运行正常且稳定 来自 BDS2006
下面是我的代码,用于解决 PE 问题 7(“找到第 10001 个素数”): #include using namespace std; bool isPrime(int n, int primes
我有两个 float 元素,右边和左边。 它们的父元素都是 text-align: center, margin: auto: 1. text 999 ' style='curso
我正在为我的 UI 元素制作一个简单的动画。 我有一个动画组件,它有 2 个不同的动画 - ZoomIn 和 ZoomOut。 每当需要在屏幕上显示 UI 元素(例如按钮)时,就会显示这些动画。 我通
我正在使用 .net 3.5 和 vb.net。我对下面提到的每种加密的内部工作知之甚少。我只使用 .net 类库中提供的类。 我有一段信息已经用 TripleDes 加密,然后是 Rijndael,
我有一个关于正确设计 php 文件及其在服务器上的存储的一般性问题。 问题是这样的:我将一个 php 对象的函数拆分到不同的 php 文件中,例如: 文件 1 AndroidFlashCard.php
我在地址表单输入上有自动完成功能。当用户点击建议时,州和邮政编码信息会自动填充。cp_state 是带有状态名称下拉列表的选择框,而cp_zipcode 是邮政编码的输入文本。 我使用下面的 java
我试图按顺序选择记录,但随机限制。 SELECT * FROM tm_winners WHERE paid_out=0 ORDER BY DESC LIMIT RAND(4,8) 但是,我似乎无法随机
我有一张这样的表,我想选取 20 位 HitTest 门的歌手并按字母顺序对他们(这 20 位歌手)进行排序。 id name hit --------------
我正在尝试使用受风影响的雨粒子,也就是 physicsWorld 重力。 我可以看到重力确实对我的 SKSpriteNode 有影响,但我无法对 SKEmitterNode 产生相同的影响。 我只是想
我有一个问题,我在网站加载时调用淡入,但由于 css 过渡效果,元素变为完全不透明,立即淡出然后淡入,我试图找到解决这个问题的方法,因为它看起来很糟糕 jQuery $(window).on("loa
我定义了一个容器元素,包含一个float div和一个ul,并且 ul 元素包含一些 float li 元素。我想清除 ul 的 float ,但 ul 的高度受其 float 兄弟元素的影响。这是
我想使用一项服务。我 100% 确信该服务可以正常工作。 服务电话 public void add(User user) { ConnectionRequest con = new Connectio
如果您在桌面/PC 上访问某人的 instagram 页面,单击搜索栏时,它会向左浮动,然后可以输入文本进行搜索。当搜索字段中没有文本时,搜索图标和“搜索”占位符会回到原来的中心位置。 我假设 jav
我是一名优秀的程序员,十分优秀!