React 功能组件在重新挂载后停止渲染状态更改

Posted

技术标签:

【中文标题】React 功能组件在重新挂载后停止渲染状态更改【英文标题】:React functional component stops rendering on state changes after remounting 【发布时间】:2021-12-22 17:04:38 【问题描述】:

对于这种奇怪情况的任何建议将不胜感激。

我有一个父组件,它监听子组件的回调状态,并根据状态呈现进度指示器。子组件是一个编辑器,使用备忘录来防止重新渲染。这是编辑器包所必需的。当父母和孩子第一次安装时一切正常,但如果父母被卸载并重新安装,它不会呈现由孩子回调触发的状态变化。

我尝试了各种方法来强制重新渲染,但似乎没有任何效果。我在状态中添加了一个计数器并延迟了更新状态。我使用 ref 作为值,因为在闭包中访问状态。

子组件是一个编辑器,监听websocket信息,异步调用handleStatus回调。重新挂载并将更新发送到 handleStatus 回调后,子组件工作正常。

父组件:

const [isConnected, setIsConnected] = useState<number>(0);
const forceUpdate = useRef<number>(0);
const statusRef = useRef('connected')


const handleStatus = (status: string) => 

    if ('connected' !== status) 
        forceUpdate.current += 1;
        setTimeout(()=>
            setIsConnected(forceUpdate.current);
        , 100)
        statusRef.current = status;
     


<div style=width: '100%' >
      statusRef.current === 'connected' ? null : <CircularProgress />
      <ChildComponent key=roomId roomId=roomId handleStatus=handleStatus/>
</div>

从调试器中,我可以看到正在调用 handleStatus,并且正在使用新值调用 setIsConnected。但是当状态改变时,父级不会渲染。

同样,父级仅在重新挂载后才停止侦听状态更新。在第一次挂载时,父级会在每次状态更新时呈现。

我们将不胜感激任何建议。

编辑: 我对父组件使用相同的键,因此 react 应该重新安装现有组件而不是创建新组件。从我所见,它看起来确实是在重新安装同一个组件,因为 ref 保留了它的值并且来自子组件的回调仍然有效。状态值是陈旧的,但这是意料之中的,因为它处于关闭状态。唯一没有意义的是我似乎无法通过更新 setState 来触发重新渲染。我什至尝试了一个状态函数,以防 setState 也变得陈旧,但这也没有用。

【问题讨论】:

【参考方案1】:

您需要使用 useEffect 并作为依赖项放置 statusRef 变量

useEffect(() => 
    
, [statusRef])

<ChildComponent key=roomId roomId=roomId handleStatus=handleStatus/>

【讨论】:

感谢您的建议,但由于父组件未在状态更改时呈现,因此未调用 useEffect。我可以从调试器中断中看到,handleStatus 回调正在被调用并且状态正在被改变,但在那之后没有其他任何事情发生。组件没有渲染,也没有调用useEffect。

以上是关于React 功能组件在重新挂载后停止渲染状态更改的主要内容,如果未能解决你的问题,请参考以下文章

为啥组件在状态更改后不重新渲染。在 react-native 函数组件中

React 功能组件在状态更改后不更新

React Native - 状态改变但组件没有重新渲染

React Native:状态更改后无法重新渲染图像

页面重新渲染/更改后如何维护组件状态?

React:如何停止重新渲染组件或对同一路由更改路由器进行 API 调用