我在功能组件中使用react useRef
获取html对象上的链接,并将其存储在Recoil atom中。例如:
const Children = () => {
const [refLink, setSrefLink] = useRecoilState(refLink)
return <input ref={someRef}/>
}
const Parent = () => {
const [refLink, setSrefLink] = useRecoilState(refLink)
const someRef = useRef();
setSomeRef(someRef)
return <Children />;
}
export const refLink = atom({
key: 'refLink',
default: null ,
});
但是,当我的父组件卸载时,我得到错误:
js:20997未捕获的类型错误:无法指派给reac-dom.development.js档案中对象'#'的只读属性'current'
我想象不出有什么问题;
3条答案
按热度按时间abithluo1#
如果您在TypeScript中遇到此错误,请尝试在type注解中列出
null
,这会将此错误从RefObject
更改为MutableRefObject
。起始日期
结束日期
执行此操作后,调用更改
current
不应导致此错误(例如,myRef.current = null
)。Source
gab6jxml2#
这里的问题是,原子在默认情况下是冻结的(请参见documentation),而ref通过修改对象的
current
属性来工作。您可以通过传递
dangerouslyAllowMutability: true
来防止对象冻结。请注意,只有当ref本身由另一个ref取代时,才会更新所有订阅者。如果ref消费者变更
current
属性,订阅者将不会重新转译,因为ref对象仍然是相同的对象。您可以通过不使用ref,而是将ref值直接传递到共享状态来解决这个问题。
在上面的场景中,我们已经完全消除了ref,而是在没有ref Package 器的情况下以反冲状态存储DOM元素。
然而,就像forward refs documentation提到的:
React组件隐藏了它们的实现细节,包括它们呈现的输出。其他使用
FancyButton
**的组件通常不需要将obtain a ref**到内部的button
DOM元素。这很好,因为它防止了组件过于依赖彼此的DOM结构。在不太了解结构和具体目标的情况下,您可以提取
Child
中的相关数据,并将其存储在共享状态中。t5zmwmid3#
你不能把一个
ref
当作道具来传递。通常情况下,组件会隐藏它的实现,这样父组件就不能访问由子组件创建的DOM元素。但是在极少数情况下,如果你想允许组件这样做,你必须使用
forwardRef
显式地这样做:the documentation中的更多内容。