react组件中使用监听函数,无法获取最新state,打印的state一直是初始默认值

export default function Travel(props) {
    const divRef = useRef(null)
    const [count, setCount] = useState(0)
    const handleClick = () => {
        console.log('click',count);
    }

    useEffect(() => {
        window.addEventListener('click', handleClick)
        return () => {
            window.removeEventListener('click', handleClick)
        }
    },[])
    console.log('out',count);


    return (
        <div ref={divRef} >
            <button onClick={() => {
        setCount(count => count + 1)

            }}>点击</button>
        </div>
    )
}

原因:
因为监听器绑定的是第一次render时生成的函数,这个函数的上下文中的state也是第一次的值,所以即便后面render了多次,因为绑定的是第一次render的函数,所以state值也是旧的

解决:


useEffect(() => {
    window.addEventListener('click', handleClick)
    return () => {
        window.removeEventListener('click', handleClick)
    }
},[count])

另一写法

export default function Travel(props) {
    const divRef = useRef(null)
    const [count, setCount] = useState(0)

    const handleClick = () => {
        console.log('click', count);
    }

    useEffect(() => {
        if (divRef && divRef.current) {
            divRef.current.addEventListener('click', handleClick)

        }
        return () => {
            divRef.current.removeEventListener('click', handleClick)

        }
    },[count])
    console.log('out', count);


    return (
        <div ref={divRef} >
            tracel
            <button onClick={() => {
                setCount(count => count + 1)

            }}>点击</button>
        </div>
    )
}

resize监听

export default function Travel(props) {
    const divRef = useRef(null)
    const [count, setCount] = useState(0)

    const handleClick = () => {
        console.log('click', count);
    }

    useEffect(() => {
      
            window.addEventListener('resize', handleClick)

        
        return () => {
            window.removeEventListener('resize', handleClick)

        }
    },[count])
    console.log('out', count);


    return (
        <div ref={divRef} >
            tracel
            <button onClick={() => {
                setCount(count => count + 1)

            }}>点击</button>
        </div>
    )
}
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐