crg*_*g63 1 javascript reactjs next.js react-hooks
我尝试将我的组件从react.component 重构为hooks,但遇到了一些麻烦。我真的不明白如何使用我的 state offsetTop。该值已设置,或在我需要时未设置。
第一次尝试:
const [offsetTop, setOffsetTop] = useState();
useEffect(() => {
setOffsetTop(window.pageYOffset + document.querySelector(".projectsContainer").getBoundingClientRect().top)
console.log(offsetTop);
window.addEventListener('scroll', handleScroll, true)
return () => window.removeEventListener("scroll", handleScroll);
}, []);
Run Code Online (Sandbox Code Playgroud)
我还尝试将它与第二种方法useEffect一起使用[offsetTop]作为第二个参数,但我的日志显示了两次 undef 和值。我明白为什么它显示两次,但仍然没有解决我的问题,我的条件不起作用。
第二次尝试:
const [offsetTop, setOffsetTop] = useState();
useEffect(() => {
setOffsetTop(window.pageYOffset + document.querySelector(".projectsContainer").getBoundingClientRect().top)
}, []);
useEffect(() => {
console.log(offsetTop);
window.addEventListener('scroll', handleScroll, true)
return () => window.removeEventListener("scroll", handleScroll);
}, [offsetTop]);
Run Code Online (Sandbox Code Playgroud)
处理滚动函数:
const [offsetTop, setOffsetTop] = useState();
useEffect(() => {
setOffsetTop(window.pageYOffset + document.querySelector(".projectsContainer").getBoundingClientRect().top)
console.log(offsetTop);
window.addEventListener('scroll', handleScroll, true)
return () => window.removeEventListener("scroll", handleScroll);
}, []);
Run Code Online (Sandbox Code Playgroud)
First try: 与放置componentDidMount() {}和使用相同的代码this可以正常工作。所以,并不是条件不好。这是关于何时设置该值以及如何设置useState和useEffect工作的问题。
Doesn't your condition work in the first variant? That one looks correct, and console.log(offsetTop) in that case is not supposed to print the newly set value, but the previously set value. To log it like you want you need:
const [offsetTop, setOffsetTop] = useState();
useEffect(() => {
setOffsetTop(window.pageYOffset + document.querySelector(".projectsContainer").getBoundingClientRect().top)
window.addEventListener('scroll', handleScroll, true)
return () => window.removeEventListener("scroll", handleScroll);
}, []);
useEffect(() => {
console.log(offsetTop);
}, [offsetTop]);
Run Code Online (Sandbox Code Playgroud)
The problem with your second try is that it does the following:
offsetTopoffsetTopoffsetTop update causes re-render
offsetTop,并再次设置您的侦听器(但它已经错过了该事件)啊...这只是你问题的一部分。
问题的第二部分是有效地从创建它并设置为侦听器的渲染周期中handleScroll()捕获值。offsetTop您应该使用与当前值useRef()保持handleScroll()同步(如果您出于其他原因不需要offsetTop,则根本不需要使用状态。您可以这样做:
const { current: heap } = useRef({
offsetTop: 0,
});
useEffect(() => {
function handleScroll() {
console.log(heap.offsetTop);
const scrolledY = window.scrollY
if(scrolledY > heap.offsetTop) console.log("works")
}
heap.offsetTop = window.pageYOffset + document.querySelector(".projectsContainer").getBoundingClientRect().top;
window.addEventListener('scroll', handleScroll, true)
return () => window.removeEventListener("scroll", handleScroll);
// The heap is guaranteed to be the same object across re-renders,
// thus including it into dependencies below does not cause useEffect
// to recompute. However, if you don't include it, and rely on ESLint
// to check code errors, it will complain about heap not being there
// as missing dependency.
}, [heap]);
Run Code Online (Sandbox Code Playgroud)
这样,offsetTop在重新渲染时是持久的,并且handleScroll()始终使用当前值。如果您还需要在更新时重新渲染offsetTop,那么您还可以使用useState()来触发重新渲染(例如将offsetTop值注入到渲染的组件中)。
| 归档时间: |
|
| 查看次数: |
1125 次 |
| 最近记录: |