-1

我对 React 中的 useEffect 和依赖数组有疑问。据我了解 useEffect 可以处理状态变化的副作用。

假设我正在创建一个像 Zoom 这样的应用程序。因此,对于接收方呼叫,当名为“callState”的局部状态变量等于应答时,我有处理 useEffect 中呼叫请求的代码:

  const [localStream, setLocalStream] = useState()
  const [remoteStream, setRemoteStream] = useState()
  const [remoteRequest, setRemoteRequest] = useState()
  const [currentUser, setCurrentUser] = useState()
  const [callState, setCallState] = useState()
  useEffect(() => {
        const answerCall = async () => {
            console.log("answering")
            if (!remoteRequest || callState !== CallState.Answering) return
            console.log('remoteStream', remoteStream)
            console.log('localStream', localStream)
            console.log('currentUser', currentUser)

            }
            answerCall()
         }, [localStream, remoteStream, remoteRequest, currentUser, callState])

这里的问题是我只想在 callState 更改时调用 answerCall useEffect 但它确实需要使用许多状态变量。我有条件if (!remoteRequest || callState !== CallState.Answering) return,所以如果 callState 没有得到回答,我会阻止 useEffect 运行,但是我不断调用 useEffect 似乎很奇怪,它实际上只意味着在 callState 更改时运行,如果其中一个状态我需要一个条件来提前保释变量,例如 localStream 更改(例如,如果我将流更改为后置摄像头)。看起来这种设计很容易出现错误和错误,即使它更具声明性。

我添加了 console.log('answering') 来说明我的观点。如果用户登录,callState 设置为挂断,当前用户刷新属性,localStream 更改.. 在所有这些情况下,它会将“应答”记录到控制台。

我可以添加 '// eslint-disable-next-line react-hooks/exhaustive-deps' 并且只添加 callState 但有很多文章对此提出警告:

https://dev.to/aman_singh/why-effects-should-t-lie-about-their-dependencies-1645

https://betterprogramming.pub/stop-lying-to-react-about-missing-dependencies-10612e9aeeda

我在这里想念什么?

4

1 回答 1

1

您只需添加callState到数组依赖项中,并将其余逻辑移动到单独的方法中,并仅在 callState 的值更改时调用 useEffect 中的方法。

  const [localStream, setLocalStream] = useState();
  const [remoteStream, setRemoteStream] = useState();
  const [remoteRequest, setRemoteRequest] = useState();
  const [currentUser, setCurrentUser] = useState();
  const [callState, setCallState] = useState();

  const answerCall = useCallback(async() => {
     console.log('remoteStream', remoteStream);
     console.log('localStream', localStream);
     console.log('currentUser', currentUser);
     console.log('remoteStream', remoteRequest);
  }, [localStream, remoteStream, remoteRequest, currentUser]);

  useEffect(() => {
     (async () => {
      if (callState) {
        answerCall()
      }
     )()
  }, [callState]);
 
于 2022-02-22T01:06:42.243 回答