Reactjs 当我使用useContext钩子时,为什么forwardRef中包装的功能组件接收空引用?

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

我有一个sidebarCart组件,基本上是一个cart组件,它被包装在forwardRef钩子中,包含UseImperializeHandle以将函数传递给父应用程序。在我引入useContext钩子之前,一切都很正常,现在sidebarCart中的ref变为空,这是什么奇怪的行为

我所说的参考文献是cartContainerpageShdowCover 我发现当停止我的nodejs服务器时,这个问题就消失了

这是侧栏车组件

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!!