Can't figure out how to use React Basic useEffect

Hello lovely community

I’m trying to make work a very simple Counter component with hooks. This is the code:

module MyApp.Components.Counter where

import Prelude

import Effect (Effect)
import Effect.Console (log)
import Data.Interpolate (i)
import Data.Tuple.Nested ((/\))
import React.Basic.DOM (button, div_, p_, text)
import React.Basic.Events (handler_)
import React.Basic.Hooks
  (Component
  , component
  , useState'
  , useEffect)

import React.Basic.Hooks as Hooks


-- TODO: use useEffect hook
-- TODO: use useReducer hook
-- TODO: add styling
-- TODO: add a material ui button

type Props = { label :: String }

logEffect :: Effect (Effect Unit)
logEffect = pure $ log "hola!"

mkCounter :: Component Props
mkCounter = component "Counter" \props -> Hooks.do

  count /\ setCount <- useState' 0

  useEffect count $ pure $ log "hi hooks"

  pure do
    div_
      [ p_ [ text $ i "You clicked " count " times" ]
      , button
          { onClick: handler_ $ setCount (count + 1)
          , children: [ text props.label ]
          }
      ]

I’d expect the useEffect to behave like the normal react one:


useEffect(() => {
    console.log("hi hooks")
}, [ count ])

The thing is that the effect runs only after I click the button.

Why doesn’t it run on the first render?

Maybe I’m missing some fundamentals, but I couldn’t find a guide focusing on this, and I’m a total newbie with ps.

This is a little tricky, and would benefit from an example in the useEffect documentation.

Runs the given effect when the component is mounted and any time the given dependencies change. The effect should return its cleanup function. For example, if the effect registers a global event listener, it should return and Effect which removes the listener.

Your current version just logs during the cleanup function. Here’s one way to change it:

logEffect :: Effect (Effect Unit)
logEffect = do
  log "hola!"
  pure $ log "cleanup"
  -- May replace the above "cleanup" line with:
  --pure $ pure unit
  useEffect count logEffect
2 Likes

Wow, thanks a lot! I’ll test that later whenever I get some free time

By the way, about this:

The effect should return its cleanup function

As your line pure $ pure unit returns an Effect (Effect Unit), does that translate into an argumentless anonymous function that does an effect? That would make sense, as the code I wrote did log effects on cleanup.

2 Likes