I'm testing react app and I have problems in rende...
# javascript
f
I'm testing react app and I have problems in render cycle with useEffect(). I added a dependency array in my useEffect for prevent render loop but ignores dependency array and render 2 times. Any hint what's going on? Code:
Copy code
val (mensajes, setMensajes) = useState(emptyArray<Json>()) //{ nick, msg, type}
val (users, setUsers)       = useState(emptyArray<Json>())

useEffect(listOf(users)) {
  socket.on("loginUser") { data ->
      console.log("OnloginUser")
      val noOfUsers = data["numOfUsers"] as Int
      val item = getMsgJson("", getParticipantsMessage(noOfUsers), "log")
      val items = mensajes.plus(item)
	  
      setMensajes(items) //render 1 time
      setUsers(data["usersList"]) //render 2 time
  }
}
c
you can also ask in #react
f
Yes, but the channel also has few members and little activity.
a
as i see effect will be called each time when list of users will be changed. So first time (and first render) with empty array of users and first subscription on socket will be created, second time it will be called when setUsers in first subscription change users (and second render will be called). Second call of that effect will create second subscription(both are alive) and in future each subscription will call setUsers and will create more and more subscriptions…
f
Second call of that effect will create second subscription(both are alive) and in future each subscription will call setUsers and will create more and more subscriptions
@Akif Abasov [JB], I didn't fully understand you in the last paragraph. I'm learning and I'm noob with React, but as I have seen in the documentation: Dependency array checks with previous value and it only renders when there is a change in that value. But in my case it is rendering when I make a change in
messages
and
users
. When only would have to do it in
users
. I created a Scratch Project with React not Kotlin-react with a similar case and there it works without multiple renders.
a
users will be changed because setUsers(data[“usersList”]) will change it and calls render, so after render call effect will be called because new users array is different than old one.
looks like you need useEffectWithCleanup(emptyList()) { … } so it will be called once and unsubscribe in cleanup phase.
f
If I know the rendering life cycle and Useffect is componentDidMount + componentDidUpdate and it will run after render. I know it will enter in useEffect on every render but not in
socket.on ("loginUser") {}
only when my server calls it at "*loginUser*". If I remove
setMessages (items)
statement works perfectly without multiple renderings. I understand what problem should be that the dependency array is not being defined correctly.
a
you have 2 problems here - incorrect dependencies and subscription leak (each socket.on should be unsubscribed after component removing or new subscription)