Reactjs 当我使用useContext钩子时,为什么forwardRef中包装的功能组件接收空引用?
我有一个sidebarCart组件,基本上是一个cart组件,它被包装在forwardRef钩子中,包含UseImperializeHandle以将函数传递给父应用程序。在我引入useContext钩子之前,一切都很正常,现在sidebarCart中的ref变为空,这是什么奇怪的行为 我所说的参考文献是cartContainer和pageShdowCover 我发现当停止我的nodejs服务器时,这个问题就消失了 这是侧栏车组件Reactjs 当我使用useContext钩子时,为什么forwardRef中包装的功能组件接收空引用?,reactjs,react-hooks,context-api,react-forwardref,Reactjs,React Hooks,Context Api,React Forwardref,我有一个sidebarCart组件,基本上是一个cart组件,它被包装在forwardRef钩子中,包含UseImperializeHandle以将函数传递给父应用程序。在我引入useContext钩子之前,一切都很正常,现在sidebarCart中的ref变为空,这是什么奇怪的行为 我所说的参考文献是cartContainer和pageShdowCover 我发现当停止我的nodejs服务器时,这个问题就消失了 这是侧栏车组件 import React ,{createRef,forwardR
import React ,{createRef,forwardRef,useImperativeHandle,useContext,useEffect}from 'react'
import CartItem from './CartItem'
import {MyContext} from '../../Context/ProductsProvider'
const SideBarCart=forwardRef((props,ref)=>{
const {setCart,cart} =useContext(MyContext)
const cartContainer = createRef()
const pageShdowCover = createRef()
const slideOut=e=>{
cartContainer.current.style.right='-400px'
pageShdowCover.current.style.opacity='0'
setTimeout(()=>pageShdowCover.current.style.display='none', 600);
}
useImperativeHandle(ref, () => ({
slideIn(){
pageShdowCover.current.style.display='block'
cartContainer.current.style.right='0'
pageShdowCover.current.style.opacity='1'
}
}),[pageShdowCover,cartContainer]);
return (
<div>
<div className="pageShdowCover" ref={pageShdowCover} ></div>
<div className="SideContainer cart" ref={cartContainer}>
<div className="cart__top">
<h1>Cart</h1>
<i className="far fa-times-circle Close" onClick={slideOut}></i>
<a onClick={slideOut}>x</a>
</div>
<div className="cart__body">
</div>
</div>
</div>
)
})
export default SideBarCart
import React,{createRef,forwardRef,useImperialiveHandle,useContext,useEffect}来自“React”
从“./CartItem”导入CartItem
从“../../Context/ProductsProvider”导入{MyContext}
const SideBarCart=forwardRef((道具,ref)=>{
const{setCart,cart}=useContext(MyContext)
const cartContainer=createRef()
const pageShdowCover=createRef()
常数滑出=e=>{
cartContainer.current.style.right='-400px'
pageShdowCover.current.style.opacity='0'
setTimeout(()=>pageShdowCover.current.style.display='none',600);
}
使用命令式句柄(参考,()=>({
slideIn(){
pageShdowCover.current.style.display='block'
cartContainer.current.style.right='0'
pageShdowCover.current.style.opacity='1'
}
}),[pageShdowCover,cartContainer]);
返回(
运货马车
x
)
})
导出默认边栏车
我认为useContext
钩子将导致子级重新查找,而不需要父级重新查找。REF在更改时不会触发重新渲染器,因此从父级传递给子级的REF可能已过时?(我认为这是答案——我可能不对)
总之(对我有效的):为了解决我遇到的问题,只需将ref存储在状态中,以便在ref更改时触发重新渲染
===
解释
我的用例是我有一个具有4个子组件的父组件。其中一个子项是标题,我希望兄弟姐妹在使用ReactDOM.createPortal
- Parent
- Header
- A
- B
- C
我发现,如果我只使用了一个ref,那么当ref被分配给DOM时,父对象不会被重新提交,因此组件a
,B
,C
不会被重新提交,因此它们不知道新分配的ref.current
值
也就是说,以下情况不起作用
const Parent=()=>{
const ref=useRef()
返回(
{ref.current=el}/>
)
}
//A、B、C有相同的签名
常数A=forwardRef((道具,ref)=>{
返回(
{createPortal(,ref.current)}
)
})
我在StackOverflow上找到了解决这个问题的方法。我提出这个问题是因为A
、B
和C
正在使用useContext(…)
。以前对我来说,当在Parent
中创建状态而不是使用上下文时,上面的代码正在工作-可能是因为Parent正在重新命名并留下过时的引用或其他东西(我认为它“意外地”工作)。i、 问题与上下文无关,而是如何触发重播
此代码不起作用
const Parent=()=>{
const[ref,setRef]=useState()
返回(
{setRef(el)}/>
)
}
//A、B、C有相同的签名
常数A=forwardRef((道具,ref)=>{
返回(
{createPortal(,ref)}
)
})
这方面有更新吗?我想我也遇到了同样的问题Hi Zack所以我为这种模式找到的解决方案是,你有一个组件,你想影响应用程序中的其他组件,首先你可以使用redux。但是简单的方法是Rxjs,你可以听一个从组件A测得的观察者,在我的示例中,Navbar的购物车链接发出一个我从购物车组件听的观察者,这是一种非常干净的方式来进行此类交互。这个答案非常清晰直观,我不敢相信我没有想到使用useState!!