Javascript ReactJS钩子vs全局变量

Javascript ReactJS钩子vs全局变量,javascript,reactjs,callback,react-hooks,Javascript,Reactjs,Callback,React Hooks,当不需要更新DOM时,我在理解挂钩方面遇到了一些困难,在我的例子中,这是一个纯粹基于逻辑的需求,我已经用挂钩和全局变量解决了这个问题。此代码表示一个简单的对等视频会议应用程序的组件。在我的例子中,我将从PeerJ检索到的调用保存在变量let calls=[]中,或者使用hooklet[calls,setCalls]=useState({calls:[],toClose:[]})中,toClose是需要关闭的调用。然后,我使用Effect钩子删除基于toClose变量的调用。最佳解决方案是什么?为

当不需要更新DOM时,我在理解挂钩方面遇到了一些困难,在我的例子中,这是一个纯粹基于逻辑的需求,我已经用挂钩和全局变量解决了这个问题。此代码表示一个简单的对等视频会议应用程序的组件。在我的例子中,我将从PeerJ检索到的调用保存在变量
let calls=[]
中,或者使用hook
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)
    })

    ...
  }
由于我使用了折衷的方法解决了我的问题,我保留了out-react范围变量,但添加了另一个封装视频的组件,这将允许我在卸载该组件后关闭调用

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;
import React,{useffect,useState,useRef}来自'React';
从“./Video”导入视频
导入“/CallStream.css”;
函数CallStream({call,stream}){
useffect(()=>{
return()=>{
call.close()
}
}, [])
返回(
);
}
导出默认调用流;

我认为您缺少了一个中间点,即不使用组件状态来存储调用(即使用范围外变量),但仍然使用effect hook用于组件的装载/卸载生命周期,即在组件卸载时关闭连接。使用react状态可以让事情变得更确定。哦,我明白了!,因此,可能使用CallStream之类的组件,我会调用Effect钩子的cleanup返回函数中的call.close()函数!我需要做的就是在调用结束后删除该组件,因为它只会在调用结束后被调用,所以不需要钩子来检查它是否已更新,谢谢!