注意: 以下这些问题的出现都是因为我们对useEffect的不熟悉导致的;可以多看看react官网;多实践;
在useEffect中绑定了事件,但是没有触发 这是因为不太了解useEffect的原理和如何使用,如果你绑定的事件dom是动态加载的,就需要加载完此dom之后再去监听这个事件,要不然就会有在useEffect中拿不到需要监听的dom的情况发生;这个时候我们就需要了解useEffect中的第二个参数,useEffect第二个参数是一个数组,这个数组中可以是变量,也可以是函数,意思就是,当第二个参数中的变量或者函数发生变化之后就会触发这个useEffect函数,如果你在此useEffect中操作的内容需要依赖这个变量的话,一定要在第二个参数中加上这个变量,不然的话你就获取不到这个变量最新的值(个人理解);所以如果你操作的dom是动态添加的,就需要在第二个参数中加入这个动态的数据;不然的话就获取不到这个动态添加的dom;(后边有栗子)
事件多次触发 需要了解useEffect中return的函数表示的是这个useEffect卸载的时候需要操作的业务内容;在useEffect中如果使用了addEventListener, 切记在此useEffect卸载的时候解除事件绑定,不然的话可能会出现多次触发的情况,比如此useEffect第二个参数是一个变量,这个变量是一直操作变化的,每次变化都会进入都这个useEffect中,导致你在这个useEffect中多次绑定了事件,所以会多次触发;
上代码
// 一个移动端的长按事件监听 let timeOutEvent; useEffect(() => { const relationUser = $('#relative')[0]; if (relateLists && relateLists.length > 0 ) { relationUser.addEventListener('touchstart', handleTouchstart); relationUser.addEventListener('touchmove', handleClear); relationUser.addEventListener('touchend', handleClear); } return () => { // useEffect卸载时解绑 relationUser.removeEventListener('touchstart', handleTouchstart) relationUser.removeEventListener('touchmove', handleClear) relationUser.removeEventListener('touchend', handleClear) } },[relateLists]) // 第二个参数为一个dom依赖的数据 const handleTouchstart = (e) => { clearTimeout(timeOutEvent); timeOutEvent = setTimeout(function () { delRelationUser(e); }, 300); } const handleClear = () => { clearTimeout(timeOutEvent); }