Reactjs useState在useEffect内未按预期工作

Reactjs useState在useEffect内未按预期工作,reactjs,Reactjs,我想跟踪用户是否位于页面顶部,或者是否已向下滚动以相应地更改页眉。这是我的密码 const [isTop, changeIsTop] = useState(true) useEffect(() => { const handleScroll = () => { changeIsTop(window.scrollY < 100) } window.addEventListener("scroll", handleScroll) return () =&

我想跟踪用户是否位于页面顶部,或者是否已向下滚动以相应地更改页眉。这是我的密码

const [isTop, changeIsTop] = useState(true)

useEffect(() => {
  const handleScroll = () => {
    changeIsTop(window.scrollY < 100)
  }

  window.addEventListener("scroll", handleScroll)
  return () => {
    window.removeEventListener("scroll", handleScroll)
  }
}, [])
const[isTop,changeIsTop]=useState(true)
useffect(()=>{
常量handleScroll=()=>{
changeIsTop(window.scrollY<100)
}
window.addEventListener(“滚动”,handleScroll)
return()=>{
window.removeEventListener(“滚动”,手柄滚动)
}
}, [])

changeisTop
不起任何作用<代码>isTop始终设置为其初始值。知道为什么会发生这种情况吗?

您的代码应该工作正常(经过测试),我唯一建议的是在初始装载时只注册一次回调:

 const [isTop, changeIsTop] = useState(true);

 const handleScroll = useCallback(() => {
    changeIsTop(window.scrollY < 100)
  }, []);

  useEffect(() => {
    window.addEventListener("scroll", handleScroll)
    return () => { window.removeEventListener("scroll", handleScroll) }
  }, [handleScroll])

你会发现,如果你
console.log(isTop)
handleScroll
中,
isTop
将是'bla'(永远的字符串!!),但在你的组件中,它将在第一次
changeIsTop(window.scrollY<100)
发生后被转换成
布尔值。

你的代码运行得很好。您正在以正确的方式设置事件侦听器

useEffect(() =>{
    const listener = () => {}
    window.addEventListener('click', listener)
    return () => window.removeEventListener('click', listener)
},[])
此效果将仅在组件的第一次装载中运行(相当于
componentDidMount
)。安装组件时,侦听器将连接到全局
单击
事件,并且每次
单击
时都将调用
侦听器
。您的问题是打印值的位置。请记住,
useffect
将只运行一次,因此如果您在
useffect
中运行
console.log
,您将看到它的初始值(在
listener
连接之前)

console.log
输入正确的值,请将其置于
useffect

useEffect(() =>{
    const listener = () => {}
    window.addEventListener('click', listener)
    return () => window.removeEventListener('click', listener)
},[])
console.log('run every render')

为什么要使用
[]
?我想去掉它应该可以解决你的问题。不会的。他正在传递
[]
,以确保效果只运行一次。如果在第一个效果之后发生滚动,该怎么办?。你的代码似乎工作得很好。我认为你应该在
useffect
之外设置
handleScroll
。所以你是说内部useffect isTop将是它的初始值。那么封口不起作用了,对吗?。传统上,一个函数应该包含一个变量,即使它不在它的作用域内。我是说当
useffect
运行时(第一次装载),isTop是
false
(初始值),并且在
滚动时只会更改。因此,当您记录
isTop
no
scroll
事件发生时。那么为什么在这个沙盒中,即使在滚动上,isTop在控制台上也总是返回true呢?下面的行应该会更改其值。
useEffect(() =>{
    const listener = () => {}
    window.addEventListener('click', listener)
    console.log('only run once')
    return () => window.removeEventListener('click', listener)
},[])
useEffect(() =>{
    const listener = () => {}
    window.addEventListener('click', listener)
    return () => window.removeEventListener('click', listener)
},[])
console.log('run every render')