React 自定义 Hook 使用 useRef 在第一次调用组件加载时返回 null?

Rah*_*ngh 3 reactjs react-hooks

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

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

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

<div ref={useComponentIntoView()}>
Run Code Online (Sandbox Code Playgroud)

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

Alv*_*aro 6

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

const MyComponent = props => {
    const ref = useRef(null);

    useEffect(() => {
        if (ref.current) {
            window.scrollTo(0, ref.current.offsetTop);
        }
    }, []);

    return <div ref={ref} />;
};
Run Code Online (Sandbox Code Playgroud)

为了让这个功能脱离组件,在它自己的 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} />;
};
Run Code Online (Sandbox Code Playgroud)

我们也可以在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>
    );
};
Run Code Online (Sandbox Code Playgroud)

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