ReactJS Hooks 与全局变量

ReactJS Hooks vs global variable

当不需要更新 DOM 时,我在理解挂钩时遇到了一些麻烦,在我的例子中,这是一个纯粹基于逻辑的需求,我已经用挂钩和全局变量解决了这个问题。此代码表示简单对等视频会议应用程序的一个组件。在我的例子中,我将从 peerJS 检索到的调用保存在变量 let calls = [] 中或使用挂钩 let [calls, setCalls] = useState({ calls: [], toClose: [] }),其中 toClose 是需要关闭的调用。然后我使用 Effect 挂钩删除基于 toClose 变量的调用。什么是最好的解决方案,为什么?我是不是遗漏了一些关于钩子的东西,它们不应该用于这种逻辑需求吗?

基于挂钩:

...
let [calls, setCalls] = useState({ calls: [], toClose: [] })

useEffect(() => {
console.log(calls)
if (calls.toClose.length != 0) {
    setCalls((calls) => {
    return {
        calls: calls.calls.filter((call) => {
        if (calls.toClose.includes(call.peer)) {
            call.close()
            return false
        } else {
            return true
        }
        }),
        toClose: []
    }
    })

}
}, [calls])


peer.on('call', (call) => {
    ...
    setCalls((calls) => { return { calls: [...calls.calls, call], toClose: calls.toClose } })
})


socket.on('user-disconnected', id => {
    setCalls((calls) => { return { calls: calls.calls, toClose: [...calls.toClose, id] } })
    ...
})

socket.on('user-connected', (id) => {
    setCalls((calls) => { return { calls: [...calls.calls, call], toClose: calls.toClose } })
})
...

基于全局变量:


let calls = []

function Room(props) {
    ...
    peer.on('call', (call) => {
      ...
      calls.push(call)
    })

    socket.on('user-disconnected', id => {
      calls = calls.filter((call) => {
        if (call.peer == id) {
          call.close()
          console.log('Closed')
          return false
        } else {
          return true
        }
      })
    })

    socket.on('user-connected', (id) => {
        ...
        calls.push(call)
    })

    ...
  }

感谢 @Drew Reese 我使用中间方法解决了我的问题,我保留了 out-of-react-scope 变量但添加了另一个封装我的视频的组件,这将让我关闭调用卸载该组件后。

import React, { useEffect, useState, useRef } from 'react';
import Video from './Video'
import './CallStream.css';

function CallStream({ call, stream }) {

    useEffect(() => {
        return () => {
            call.close()
        }
    }, [])

    return (
        <Video stream={stream}></Video>
    );
}

export default CallStream;