why-did-you-render icon indicating copy to clipboard operation
why-did-you-render copied to clipboard

Breaks child.type comparisons

Open brandonkal opened this issue 6 years ago • 5 comments

This will always return an empty array when activated:

const MenuItem = React.forwardRef((props, ref) => { return <div>Example</div> })
MenuItem.whyDidYouRender = true

let focusableChildrenTypes = [MenuItem]

let isFocusableChildType = (child): child is React.ReactElement =>
  focusableChildrenTypes.includes(child.type)
let getFocusableMenuChildren = (children) => {
  let focusable: any[] = []
  React.Children.forEach(children, (child) => {
    console.log('Checking focusable', child.type === MenuItem)
    if (isFocusableChildType(child)) focusable.push(child)
  })
  return focusable
}

Is there a way to get this module to work with child.type comparisons? Thank you.

brandonkal avatar Aug 05 '19 00:08 brandonkal

Proved this happens with a failing test on branch children-types: https://github.com/welldone-software/why-did-you-render/tree/children-types

vzaidman avatar Sep 09 '19 16:09 vzaidman

This is actually not surprising. Currently we track how a functional component changes by substituting it with another functional component that tracks props and renders the original functional component.

The type of any component that is rendered with "whyDidYouRender" enabled on it is indeed "WDYRFunctionalComponent" (instead of the expected "MenuItem" in this case).

A deep refactor is needed to deal with it- we need to somehow get access to every render of a Component's instance (React element) without substituting it with another one.

But- I consider this an edge case though because child.type is not documented (as far as I can tell) and no one should rely on it anyway, so it's a low priority for me. (Can be interesting to solve though)

vzaidman avatar Sep 09 '19 16:09 vzaidman

A workaround (not a very satisfying one, I know) is to use displayName instead of type like this:

child.displayName === MenuItem.displayName

vzaidman avatar Sep 09 '19 16:09 vzaidman

Perhaps the type getter could be monkey patched to return the type of the child if type is called on a WDYRFunctionalComponent wrapper.

brandonkal avatar Sep 09 '19 18:09 brandonkal

Perhaps the type getter could be monkey patched to return the type of the child if type is called on a WDYRFunctionalComponent wrapper.

I tried it. This can't be done. the type getter is strictly read only :(

vzaidman avatar Oct 04 '19 06:10 vzaidman