React.memo recommended usage
2jt opened this issue · 4 comments
Hi, what would be the recommended way to use React.memo?
In this snippet barMemo { otherValue } should not have printed in its render when the text input changes. As @ptrfrncsmrph has pointed out, changing the call to barMemo otherValue would make it work. So it is because of { otherValue }, every time barMemo is called with { otherValue }, a new object is created and as React.memo uses reference equality, it is normal, that the component barMemo re-renders.
I've found myself reaching for this feature, because I have a big form and one input triggers the re-render of the rest of them. Wrapping the parts of the form in memo, I hope the performance would improve. Or am I wrong?
Thanks
This is the problem: React.element c <<< { nested: _ }
memo is just React's memo, so it expects an actual ReactComponent and looks through the props object with shallow reference equality.
It works if you use it directly on a ReactComponent version of your component: modified snippet
memo's type is kind of weird though.. I think it should just be
memo ::
forall props.
ReactComponent props ->
Effect (ReactComponent props)I've considered having both memo and memoReactComponent, where the latter is just React's function using ref equality and the former is forall props. Eq props => (props -> JSX) -> Component props.. but it's also already possible to write nearly the same thing using useMemo:
mkBarMemo ::
Component
{ otherValue :: String
}
mkBarMemo = do
barMemo <- React.component "BarMemo" \{ otherValue } -> React.do
React.unsafeRenderEffect $ log "this should not re-rendered"
pure
$ R.div_ [ R.text $ "Memo bar" ]
React.component "BarMemoWrapper" \props -> React.do
React.useMemo props \_ -> barMemo props
-- ^ TryPureScript's version of react-basic-hooks is very old
-- so to test it there you'll need to rename this to `useLazy`Edit: to clarify, this useMemo version is using PureScript's Eq props instead of shallow reference equality. This is more "PureScript-like" but could potentially be even slower than a regular re-render if props has a complicated Eq instance.
Thank you!