我创建了一个自定义钩子,以在滚动组件时将元素滚动回到视图中。
export const useComponentIntoView = () => {
const ref = useRef();
const {current} = ref;
if (current) {
window.scrollTo(0, current.offsetTop );
}
return ref;
}
现在,我在
这样的功能组件中使用了此功能<div ref={useComponentIntoView()}>
因此,第一次电流总是为null,我知道该组件仍未安装,因此该值为null。但是我们总是可以在我的自定义钩子中取得这个值的原因,因为仅对于第一次导航,组件滚动不起作用。有没有解决这个问题的办法。
答案 0 :(得分:1)
我们已经从ref
中读取了useEffect
,如果已经分配了它。要仅在安装时调用它,我们传递一个空的依赖项数组:
const MyComponent = props => {
const ref = useRef(null);
useEffect(() => {
if (ref.current) {
window.scrollTo(0, ref.current.offsetTop);
}
}, []);
return <div ref={ref} />;
};
为了在组件本身中拥有此功能,我们可以采用以下方式:
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
钩子。在这种情况下,我们需要将其传递给依赖项数组,该数组属于一个状态。此变量可以属于同一Component或祖先。例如:
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
回调。
答案 1 :(得分:0)
正如您提到的,ref.current
是null
,直到组件安装完毕。您可以在此处使用useEffect
-在安装组件后即会触发,即:
const useComponentIntoView = () => {
const ref = useRef();
useEffect(() => {
if (ref.current) {
window.scrollTo(0, ref.current.offsetTop );
}
});
return ref;
}