使用React Hooks滚动到页面加载上的元素



我正在尝试创建一个功能组件,该组件从API获取数据并将其呈现到列表中。在获取并呈现数据后,我想检查URL id和列表项是否相等,如果相等,则列表项应该滚动到视图中。

以下是我的代码:

import React, { Fragment, useState, useEffect, useRef } from "react";
export default function ListComponent(props) {
const scrollTarget = useRef();
const [items, setItems] = useState([]);
const [scrollTargetItemId, setScrollTargetItemId] = useState("");
useEffect(() => {
const fetchData = async () => {
let response = await fetch("someurl").then((res) => res.json());
setItems(response);
};

fetchData();
if (props.targetId) {
setScrollTargetItemId(props.targetId)
}
if (scrollTarget.current) {
window.scrollTo(0, scrollTarget.current.offsetTop)
}
}, [props]);
let itemsToRender = [];
itemsToRender = reports.map((report) => {   
return (
<li
key={report._id}
ref={item._id === scrollTargetItemId ? scrollTarget : null}
>
{item.payload}
</li>
);
});
return (
<Fragment>
<ul>{itemsToRender}</ul>
</Fragment>
);
}

我的问题是scrollTarget.current总是undefined。请告诉我做错了什么。提前谢谢。

正如@yagiro所建议的那样,使用useCallback就成功了!

我的代码最终是这样的:

const scroll = useCallback(node => {
if (node !== null) {
window.scrollTo({
top: node.getBoundingClientRect().top,
behavior: "smooth"
})
}
}, []);

然后我只是有条件地在你想要滚动到的节点上设置ref={scroll}

这是因为当引用发生更改时,不会导致重新渲染。

根据React的文档:https://reactjs.org/docs/hooks-reference.html#useref

请记住,useRef不会在其内容更改时通知您。更改.current属性不会导致重新渲染。如果您想在React将ref附加或分离到DOM节点时运行一些代码,您可能需要使用callback ref

constructor(props) {
thi.modal = React.createRef();

}

handleSwitch() {
// debugger
this.setState({ errors: [] }, function () {
this.modal.current.openModal('signup') // it will call function of child component of Modal
});
// debugger
}


return(
<>

<button className="login-button" onClick={this.handleSwitch}>Log in with email</button>

<Modal ref={this.modal} />
</>
)

React Hooks将延迟滚动,直到页面准备好:

useEffect(() => {
const element = document.getElementById('id')
if (element)
element.scrollIntoView({ behavior: 'smooth' })
}, [])

如果元素是动态的并且基于变量,则将它们添加到效果挂钩:

const [variable, setVariable] = useState()
const id = 'id'
useEffect(() => {
const element = document.getElementById(id)
if (element)
element.scrollIntoView({ behavior: 'smooth' })
}, [variable])

最新更新