-
-
Notifications
You must be signed in to change notification settings - Fork 227
Conversation
I wonder if we could add a check in developement mode to warn in case the modifiers object has the same content but changed identity? |
@@ -120,15 +130,7 @@ const Demo = enhance( | |||
? ({ rotation, scale, opacity, top: topOffset }) => ( | |||
<Popper | |||
placement="bottom" | |||
modifiers={{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the warning allowed me to catch us over updating the modifiers object in the demo here!
328d50a
to
0ba3ea2
Compare
done! |
Cool thanks! I'm gonna test it out and merge it, it may take a few days unfortunately so I say sorry in advance! |
src/Popper.js
Outdated
) { | ||
|
||
// develop only check that modifiers isn't being updated needlessly | ||
if ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is Terser/Uglify/etc able to strip out this kind of condition?
Could we split it into two conditions to help the tools?
if (process.env.NODE_ENV === 'development') {
if (this.props.modifiers !== prevProps.modifiers &&
this.props.modifiers != null &&
prevProps.modifiers != null &&
shallowEqual(this.props.modifiers, prevProps.modifiers)
) {
[...]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
Currently if a consumer updates the `modifiers` object prop, unless another prop also changes, the new modifiers are not applied. For example, if the passed modifier `flip.enabled` were to change from `true` to `false`, the popper doesn't pick up on that fact and continues allowing the popover contents to flip. This PR allows for the `Popper` component to construct a new popper instance with the new modifiers if and only if the `modifiers` object changes (note: this is a reference comparison and not a value comparison). I'm not that familiar with Popper.JS so if there is a more efficient way to make sure modifier changes get propagated to the underlying popover, please let me know! As it stands, this _could_ cause some unnecessary popper instance creation/destruction if the consumer isn't properly memoizing the `modifiers` object they pass. This could be partially solved by doing something like shallow comparing each modifier option object one by one instead of a top level reference comparison. Alternatively, if there is a more performant way to imperatively update an existing popper instance, that may be better to use to avoid as much churn. In fact, it would be even possible to combine both of these solutions as well.
Currently if a consumer updates the
modifiers
object prop, unless another prop also changes, the new modifiers are not applied. For example, if the passed modifierflip.enabled
were to change fromtrue
tofalse
, the popper doesn't pick up on that fact and continues allowing the popover contents to flip.This PR allows for the
Popper
component to construct a new popper instance with the new modifiers if and only if themodifiers
object changes (note: this is a reference comparison and not a value comparison).I'm not that familiar with Popper.JS so if there is a more efficient way to make sure modifier changes get propagated to the underlying popover, please let me know!
As it stands, this could cause some unnecessary popper instance creation/destruction if the consumer isn't properly memoizing the
modifiers
object they pass. This could be partially solved by doing something like shallow comparing each modifier option object one by one instead of a top level reference comparison. Alternatively, if there is a more performant way to imperatively update an existing popper instance, that may be better to use to avoid as much churn. In fact, it would be even possible to combine both of these solutions as well.