Javascript React抛出一个错误;Can';“不转让给财产”;“向左滚动”;关于1:不是对象;尝试在自定义函数中使用ref时

Javascript React抛出一个错误;Can';“不转让给财产”;“向左滚动”;关于1:不是对象;尝试在自定义函数中使用ref时,javascript,reactjs,react-redux,Javascript,Reactjs,React Redux,我有一个使用“useRef”钩子制作的对象的工作动画。此动画中的部分代码将重复多次,因此我将其移动到一个单独的函数中,但当我尝试调用此函数时,在渲染组件时,我在1:not a object上遇到错误“Can not assign to property”scrollLeft“可能有什么问题?” codesandbox上的完整代码 import React,{useState,useffect,useRef}来自“React” 常量可滚动=道具=>{ 常量项=道具项; 设ref=useRef

我有一个使用“useRef”钩子制作的对象的工作动画。此动画中的部分代码将重复多次,因此我将其移动到一个单独的函数中,但当我尝试调用此函数时,在渲染组件时,我在1:not a object上遇到错误“Can not assign to property”scrollLeft“可能有什么问题?”

codesandbox上的完整代码

import React,{useState,useffect,useRef}来自“React”
常量可滚动=道具=>{
常量项=道具项;
设ref=useRef()
常量[状态,设置状态]=使用状态({
伊斯克罗林:错,
客户端:0,
scrollX:0
})
const[touchStart,setTouchStart]=useState(0);
让frameId;
const onMouseDown=e=>{…}
const onMouseUp=e=>{
if(ref&&ref.current&&ref.current.contains(e.target)){
返回;
}
e、 预防默认值()
让touchShift=touchStart-state.clientX
让雷兹;
让我们改变;
如果(触摸换档>0){
换档=300-触摸换档
rez=state.x+shift
如果(rez>2100){
雷兹=1800
取消动画帧(帧ID)
}
让速度=换档/20
设cur=state.scrollX
frameId=requestAnimationFrame(动画)
设置动画(cur、speed、rez)
}
}
常数动画=(电流、速度、rez)=>{
frameId=requestAnimationFrame(动画)
电流=电流+速度
ref.current.scrollLeft=当前固定(2)
if(数学圆整(cur)==rez){
取消动画帧(帧ID)
设定状态({
……国家,
X:rez,
伊斯克罗林:错,
})
}
}
useffect(()=>{
document.addEventListener('mousedown',onMouseDown)
document.addEventListener('mouseup',onMouseUp)
return()=>{
document.removeEventListener('mousedown',onMouseDown)
document.removeEventListener('mouseup',onMouseUp)
}
})
useffect(()=>{
ref.current=requestAnimationFrame(动画)
return()=>{
取消动画帧(参考当前)
},[]})
返回(
)
}

导出默认可滚动此错误表示您正在尝试设置数字的属性。在您的使用效果中,您正在这样做:

ref.current = requestAnimationFrame(animate)
requestAnimationFrame根据MDN返回:

一个长整型值,即请求id,用于唯一标识回调列表中的条目。这是一个非零值,但您不能对其值进行任何其他假设

但是对于DOM元素也使用相同的ref。运行useEffect后,它会将您的ref设置为rAF id,这是一个在您尝试设置ref上的scrollLeft属性时导致错误的数字


接下来,您可以尝试使用两个单独的引用来解决此问题,一个用于requestAnimationFrame,另一个用于DOM元素。

是否有类似的示例?我不明白每件事是如何实现的。我所能做的就是创建一个新的let refAnimation=useRef(),并在useffect()中使用它,而不是在ref中使用它。但是接下来要修复什么,我无法理解。现在,我的组件正在加载,但当加载组件时,animate()函数会自动开始工作,并被无限次调用,而不是在单击事件上。或者替换
frameId=requestAnimationFrame(animate)
在使用
frameId=refAnimation.current的动画函数中,这也可能是infinte循环的罪魁祸首。我不认为frameId是必要的,因为它存储在ref中。代码笔只包含JS,所以很难看出哪里出了问题。你可以试着把它放在一个代码沙箱里。“ref.current为null”的错误是正常的,因为未设置初始ref值,您可以通过在执行动画之前先检查ref是否已设置来修复此错误。我让它们都使用单独的动画功能。useEffect设置不正确,您必须将动画func参数传递给rAF回调才能正常工作。衷心感谢您。现在我要弄清楚它是如何工作的。