【问题标题】:Restore scroll position in React Hooks with useRef is shaky使用 useRef 恢复 React Hooks 中的滚动位置不稳定
【发布时间】:2019-12-06 20:30:50
【问题描述】:

我想通过在 useEffect 中将窗口位置设置回之前的状态来滚动到之前的窗口位置。为了获得之前的状态,我使用了 useRef。

该组件曾经是基于类的,并且可以完美运行。在我将它重构为钩子之后,这种“不稳定”的行为就开始了。

在开头声明useRef

const scrollRef = useRef(window.pageYOffset);

每当组件重新渲染时:

scrollRef.current = window.pageYOffset;

状态更新时:

useEffect(() => {
  window.scrollTo(0, scrollRef.current)
});

完整代码:

export default () => {
   const scrollRef = useRef(window.pageYOffset);
   ...
   scrollRef.current = window.pageYOffset;
   useEffect(() => {
      window.scrollTo(0, scrollRef.current)
   });

   return (
      ...
   );
}

在状态更新时,我想通过没有这种“摇晃”的行为来改回之前的窗口位置。 (摇摇晃晃的意思是看起来他滚动到顶部,然后滚动到上一个位置,所以看起来它在摇晃)

【问题讨论】:

  • 尝试添加沙盒

标签: javascript reactjs react-hooks


【解决方案1】:

您的问题的解决方案可能如下所示:

sandbox

首先创建一个自定义的usePrevious 钩子。这只是另一个函数,它使用新的useRef 方法来存储先前的滚动值,并且仅在将新值传递给它时才更新它。

// Hook
function usePrevious(value) {
  // The ref object is a generic container whose current property is mutable ...
  // ... and can hold any value, similar to an instance property on a class
  const ref = useRef();
  
  // Store current value in ref
  useEffect(() => {
    ref.current = value;
  }, [value]); // Only re-run if value changes
  
  // Return previous value (happens before update in useEffect above)
  return ref.current;
}

在实际的组件中,我们声明了一个previousPosition 变量。每次组件重新渲染时,我们的 customHook 都会以当前位置执行。它返回之前的位置,然后被分配。

同样在每次渲染时,useEffect 方法正在执行,因为我们没有将数组作为第二个参数传递。在那里我们只是将当前滚动位置与 上一个并滚动回上一个,以防它发生变化。

function Scroll(props){
  const prevPosition = usePrevious(window.pageYOffset);
   // Update scoll position with each update
   useEffect(() => {
     if(window.pageYOffset !== prevPosition){
         window.scrollTo(0, prevPosition);
     }  
   });

   return (
      <div>
      ...
      </div>
   );
}

【讨论】:

    【解决方案2】:

    如果我理解正确,请使用useLayoutEffect 而不是useEffect。这将在渲染组件之前滚动回顶部。记得添加依赖数组。

    【讨论】:

      猜你喜欢
      • 2021-08-27
      • 2022-10-19
      • 1970-01-01
      • 2011-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多