使用 useRef 反应自定义钩子在调用组件加载时返回 null?



我创建了一个自定义钩子,以便在滚动组件时将元素滚动回视图中。

export const useComponentIntoView = () => {
  const ref = useRef();
  const {current} = ref;
  if (current) {
    window.scrollTo(0, current.offsetTop );
  }
  return ref;
}

现在我正在一个功能组件中使用它,例如

<div ref={useComponentIntoView()}>

所以第一次电流总是为空,我知道组件仍未挂载,因此值为 null . 但是我们可以做些什么来在我的自定义钩子中始终获取此值,因为仅在第一次导航时组件滚动不起作用.有没有解决这个问题的方法.

我们需要从 useEffect 中读取ref,当它已经被分配时。为了仅在挂载时调用它,我们传递一个空的依赖项数组:

const MyComponent = props => {
    const ref = useRef(null);
    useEffect(() => {
        if (ref.current) {
            window.scrollTo(0, ref.current.offsetTop);
        }
    }, []);
    return <div ref={ref} />;
};

为了在组件中摆脱此功能,在它自己的 Hook 中,我们可以这样做:

const useComponentIntoView = () => {
    const ref = useRef(null);
    useEffect(() => {
        if (ref.current) {
            window.scrollTo(0, ref.current.offsetTop);
        }
    }, []);
    return ref;
};
const MyComponent = props => {
    const ref = useComponentIntoView();
    return <div ref={ref} />;
};

我们还可以在进行一定更改后运行useEffect钩子。在这种情况下,我们需要传递给它的依赖项数组,一个属于状态的变量。此变量可以属于同一组件或祖先组件。例如:

const MyComponent = props => {
    const [counter, setCounter] = useState(0);
    const ref = useRef(null);
    useEffect(() => {
        if (ref.current) {
            window.scrollTo(0, ref.current.offsetTop);
        }
    }, [counter]);
    return (
        <div ref={ref}>
            <button onClick={() => setCounter(counter => counter + 1)}>
                Click me
            </button>
        </div>
    );
};

在上面的示例中,每次单击按钮时,它都会更新计数器状态。此更新会触发新的呈现,并且由于计数器值自上次调用 useEffect 以来发生了变化,它将运行useEffect回调。

正如您所提到的,ref.current null,直到组件挂载之后。这是您可以使用useEffect的地方 - 它将在组件挂载后触发,即:

const useComponentIntoView = () => {
  const ref = useRef();
  useEffect(() => {
    if (ref.current) {
      window.scrollTo(0, ref.current.offsetTop );
    }
  });
  return ref;
}

相关内容

  • 没有找到相关文章

最新更新