我将尽量保持简短,但是我不确定100%正确的方法来实现我的目标。我在没有太多培训的情况下就陷入了React的深渊,所以我很可能会错误地处理大部分此组件,正确方向的观点肯定会有所帮助,我真的不希望有人完全重做对我来说是我的组成部分,因为它很长。
我有一个导航栏SubNav
,该导航栏基于url / path查找当前处于活动状态的项目,然后将移动下划线元素,该元素继承了活动元素的宽度。为此,我找到了活动项目的位置以及相应的位置。当用户将鼠标悬停在另一个导航项上或调整窗口大小时,也会相应地调整位置。
在较低分辨率下,当导航被切断以使箭头在导航上向左/向右滚动以查看所有导航项目时,我也有它。
此外,如果分辨率较低且当前处于活动状态的导航项目不在屏幕上,则导航将滚动到该项目,然后正确定位下划线。
目前,此功能与组件中的功能相同,但问题是,我不正确地执行此操作,我正在使用lodash
函数delay
来延迟某些时间(我想得到某些导航项的正确位置,因为在函数调用时这是不正确的),我觉得这不是走的路。这完全取决于页面加载的速度等,并且每个用户的浏览速度都不一样。
_.delay(
() => {
setSizes(getSizes()),
updateRightArrow(findItemInView(elsRef.length - 1)),
updateLeftArrow(findItemInView(0));
},
400,
setArrowStyle(styling)
);
不使用延迟,从我的状态返回的值是错误的,因为尚未设置。
我的问题是,我该如何正确处理?我知道我的以下代码有些可读性,但是我提供了一个CODESANBOX来玩。
我有3个主要功能,它们相互依赖:
getPostion()
left
位置,使其成为屏幕上最左侧的导航项,并通过{{ 1}}将下划线直接移到下面。setSizes(getSizes())
getSizes()
中的参数以更新setSizes
状态,该状态将返回所有导航项的左右边界sizes
getUnderlineStyle()
函数中setUnderLineStyle
中的一个参数,用于相对于从getSizes()
状态抓取的活动导航项的位置来更新下划线对象的位置,但由于状态尚未设置,因此我必须在sizes
中将sizesObj
作为参数传递。我认为这是我开始困惑的地方,我想给人的印象是,当我设置状态时,便可以访问它。因此,我开始使用setSizes
进行战斗。下面是我的整个组件,但可以在CODESANBOX中看到它
delay
答案 0 :(得分:2)
您可以使用useLayoutEffect
挂钩来确定值是否已更新并采取措施。由于要确定是否所有值都已更新,因此需要在useEffect中比较新旧值。您可以参考以下文章,了解如何编写usePrevious
自定义钩子
How to compare oldValues and newValues on React Hooks useEffect?
const oldData = usePrevious({ rightArrow, leftArrow, sizes});
useLayoutEffect(() => {
const {rightArrow: oldRightArrow, leftArrow: oldLeftArrow, sizes: oldSizes } = oldData;
if(oldRightArrow !== rightArrow && oldLeftArrow !== leftArrow and oldSizes !== sizes) {
setArrowStyle(styling)
}
}, [rightArrow, leftArrow, sizes])
答案 1 :(得分:0)
setState
带有可选的second argument,这是在状态更新和组件重新呈现后执行的回调。
另一种选择是componentDidUpdate
生命周期方法。
答案 2 :(得分:0)
我认为您需要延迟的原因在这里,因为您是根据第一个和最后一个元素的矩形进行计算的,这些矩形在单击按钮并进行500ms滚动动画时会受到影响。因此,您的计算需要等待动画完成。更改动画的数量并延迟您将看到的关系。
我的意思。
@include transition(all 500ms ease);
简而言之,只要您有与计算相关的动画,我认为您使用的是正确的方法。