Description
Hi there, when I try to create recursive react components, e.g. a folder structure UI:
RecursiveFolderComponent
├── RecursiveFolderComponent
│ ├── RecursiveFolderComponent
│ ├── RecursiveFolderComponent
├── RecursiveFolderComponent
├── RecursiveFolderComponent
│ ├── RecursiveFolderComponent
├── RecursiveFolderComponent
I am hit with problems of all children components un-mounting and re-rendering (and React.memo
also fails to work) when the parent component's state is updated.
I can make it work by using impure unsafePerformEffect
like so:
recursiveFolder ∷ ReactComponent { folderId ∷ Int }
recursiveFolder = unsafePerformEffect $ memo' eq $
-- ^ If I do not use `unsafePerformEffect`,
-- subfolder components will keep unmount and re-render
reactComponent "RecursiveComponent" \props -> React.do
...
let
arrOfSubFolders = const (element recursiveFolder { folderId: props.folderId - 1 })
<$> (mkRows props.folderId)
pure $ ...
, React.fragment arrOfSubFolders
...
I have made a minimal reproducible code at:
If I do not use unsafePerformEffect
, the children sub components will always un-mount and re-render, and I have to use unsafeRenderEffect
in the middle of the component anyway (see below):
I think the issue is (to quote your succinct comment):
React uses function instances as component identity. ... Creating component functions during render results in forced unmouting and remounting of the entire tree below that component...
Originally posted by @megamaddu in #12 (comment)
Is there no other way to achieve memoization of recursive children components in Purescript without using unsafePerformEffect
/ unsafeRenderEffect
that might have arbitrary side-effect?
Is this one of the cases that Javascript/React refuses to play nicely with pure functional approach?
Thank you for reading through this long-winded issue.
Lastly, this is a Codepen | Typescript Implementation of how I would write it in "normal" Typescript, for refererence.