shadaj/slinky

useEffect don't cleanup

mvillafuertem opened this issue · 2 comments

Hi, I have checked that the useEffect don't cleanup. Am I wrong about something? Here my use case. Thanks

You can check this use case here: https://mvillafuertem.github.io/zio-react/hooks/ ( Follow this instruction to reproduce error

  1. open console,
  2. type 123 inside input name,
  3. move mouse and see console,
  4. delete char 3 of input name,
  5. move mouse again
    )
@react object MyConditionalComponent {

  type Props = Unit

  val component: FunctionalComponent[Props] = FunctionalComponent[Props] { _ =>
    useEffect(
      () => {

        //val eventToUnit: Event => Props = (e: Event) => println((e.asInstanceOf[raw.MouseEvent].clientX, e.asInstanceOf[raw.MouseEvent].clientY))
        val eventToUnit: Event => Props = (e: Event) => println(":D")

        window.addEventListener("mousemove", eventToUnit)
        // CleanUP
        () => window.removeEventListener("mousemove", eventToUnit)
      },
      Seq.empty. // no dependencies!
    )
    div(
      h3("You are awesome")
    )

  }

}


@react object App {

  type Props = Unit

  case class Person(name: String, email: String)

  val component: FunctionalComponent[Props] = FunctionalComponent[Props] { _ =>
    val (formState, setFormState) = useState(Person(name = "", email = ""))

    val Person(pname, pemail) = formState

    useEffect(() => println("Hey"), Seq.empty)
    useEffect(() => println("changed FormState"), Seq(formState))
    useEffect(() => println("changed Email"), Seq(pemail))

    val handleInputChange: SyntheticEvent[TagElement#RefType, Event] => Unit =
      (e: SyntheticEvent[TagElement#RefType, Event]) =>
        e.target.asInstanceOf[HTMLInputElement].name match {
          case "email" => setFormState(formState.copy(email = e.target.asInstanceOf[HTMLInputElement].value))
          case "name"  => setFormState(formState.copy(name = e.target.asInstanceOf[HTMLInputElement].value))
        }

    Fragment(
      h1("SimpleFormApp"),
      hr(),
      div(className := "form-group")(
        input(
          `type` := "text",
          name := "name",
          className := "form-control",
          placeholder := "Name",
          autoComplete := "off",
          value := pname,
          onChange := handleInputChange
        )
      ),
      div(className := "form-group")(
        input(
          `type` := "text",
          name := "email",
          className := "form-control",
          placeholder := "Email",
          autoComplete := "off",
          value := pemail,
          onChange := handleInputChange
        )
      ),
      if (pname.equals("123")) MyConditionalComponent() else null
    )

  }

}


You are experiencing an issue related to silent conversion from Scala function to js.Function twice--once during addEventListener and another during removeEventListener--each creating a new instance.

Please see https://github.com/kladdad/use-slinky-hooks/blob/master/src/main/scala/com/payalabs/slinky/hooks/EventHooks.scala#L40 for an explaination and a solution.

Thanks a lot @ramnivas !!