英文:
How to Implement EventSource with dynamic url parameters in React, satisfying exhautive deps and avoid render loop
问题
我们正在在一个React应用中实现EventSource。我有一个可用的应用,但我想改进它。
我有两个问题:
- 
我想在组件卸载之前传输完成时关闭连接。或者如果URL参数发生变化。
 - 
满足完整的依赖性检查规则。
 
现在我在useEffect中建立连接:
useEffect(() => {
  if (showResults) {
    const sse = new EventSource(
      `${AI_API_BASE_URL}?param1=${param1}&param2=${param2}`
    )
    sse.addEventListener("event", (e) => {
      const parsedData = JSON.parse(e.data, (key, value) => {
        if (key === "id") {
          return parseInt(value, 10)
        }
        return value
      })
      pushToDataArray(parsedData)
      if (parsedData.isdone === true) {
        setNumberOfTries((numberOfTries) => ({
          count: numberOfTries.count + 1,
          timestamp: Date.now(),
        }))
        setErrors([])
        sse.close()
      }
    })
    sse.onerror = (e) => {
      console.log("error", e)
      setErrors((errors) => [...errors, e])
    }
  }
  return () => {
    // TODO 关闭sse连接
    // sse.close()
  }
}, [companyDescription, projectDescription, showResults])
一个问题是,如果我将pushToDataArray添加到依赖数组中,它会陷入无限循环。另一个问题是,如果应用卸载,我无法访问sso对象以关闭连接。
有什么改进的想法吗?
也许sso可以存储为引用?
英文:
We are implementing EventSource in a React app. I have a working app, but I would like to improve it.
Two issues I have are:
I would like to close the connection if the component unmounts before the transmission is done. Or if the url parameters change.
And satisfying the exhaustive deps linting rule.
Now I establish the connection in a useEffect:
    useEffect(() => {
    if (showResults) {
      const sse = new EventSource(
        `${AI_API_BASE_URL}?param1=${param1}&param2=${param2}`
      )
      sse.addEventListener("event", (e) => {
        const parsedData = JSON.parse(e.data, (key, value) => {
          if (key === "id") {
            return parseInt(value, 10)
          }
          return value
        })
        
          pushToDataArray(parsedData)
        
        } else if (parsedData.isdone === true) {
          setNumberOfTries((numberOfTries) => ({
            count: numberOfTries.count + 1,
            timestamp: Date.now(),
          }))
          setErrors([])
          sse.close()
        }
      })
      sse.onerror = (e) => {
        console.log("error", e)
        setErrors((errors) => [...errors, e])
      }
    }
    return () => {
      // TODO close sse connection
      //sse.close()
    }
  }, [companyDescription, projectDescription, showResults])
One issue is that if I add pushToDataArray to the dependency array, it goes into an infinite loop. The other issue is that I can't close the connection if it unloads because I can't reach the sso-object.
Any ideas for improvements?
Maybe the sso could be stored as a reference?
答案1
得分: 0
Move soo out of the useEffect and make it a reference.
Implement pushToDataArray as a useReducer.
英文:
Move soo out of the useffect and make it a reference.
Implement pushToDataArray as a useReducer
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论