Formless v4 questions (dirty state and reinitialize forms)

Hi!
I’d like to know what’s the best way to check for dirty forms state and to reinitialize forms with the “new” formless api (it took me a while to catch up…).

After a bit of tinkering (and some help from discord) I got to this solution, but I wanted to know if there’s a more appropriate way to get to the same result.

I have defined two helper functions:

data DirtyProps = DirtyProps

instance
  ( Eq a
  , TE.TypeEquals (Record (value :: a, initialValue :: a | tail)) (Record row)
  ) =>
  FoldingWithIndex DirtyProps (Proxy sym) Boolean (Record row) Boolean where
  foldingWithIndex DirtyProps _prop b a = b || val1 /= val2
    where
    val1 = TE.to <<< Record.get (Proxy :: Proxy "value") <<< TE.from $ a
    val2 = TE.to <<< Record.get (Proxy :: Proxy "initialValue") <<< TE.from $ a

data ReinitForm = ReinitForm

instance
  ( TE.TypeEquals (Record (value :: a, initialValue :: a, result :: Maybe (Either e o))) (Record row)
  ) =>
  Mapping ReinitForm a (Record row) where
  mapping ReinitForm val =
    TE.to { value: val, initialValue: val, result: Nothing }
    where
    _initialValue = Proxy :: Proxy "initialValue"
    _value = Proxy :: Proxy "value"
    _result = Proxy :: Proxy "result"

-- | Checks whether a Formless form is dirty.
isFormDirty :: forall r. HFoldlWithIndex DirtyProps Boolean { | r } Boolean => { | r } -> Boolean
isFormDirty r = hfoldlWithIndex DirtyProps false r

-- | Reinitializes a Formless form with new inputs values.
reinitForm = hmap ReinitForm

In this case I have a wrapper component that contains a form. A lot of code omitted and simplified to highlight the important parts:

component = 
  Hooks.component \{slotToken } input -> Hooks.do
    Hooks.pure do
      HH.slot _form unit (form input) mempty (handleForm slotToken)

  where
  handleForm slotToken = case _ of
    Submit formRes -> do
      newInput <- someLogicAndAjaxCall
      Hooks.tell slotToken _form unit (Update newInput)

form input = F.formless { ... } input $ H.mkComponent
   ...

  where
  handleQuery = case _ of
    F.Query (Update newInput a) -> do
      { context: { formActions } } <- H.get
      handleAction $ formActions.setFields $ reinitForm newInput
      pure $ Just a
   F.Validate changed reply -> do
     { context: { fields } } <- H.get
     when isFormDirty fields $ do
        --  do some stuff like onbeforeunload
    pure $ Just $ reply $ F.validate changed etc.