react-onclickoutside: onClickOutside doesn't respond to Composed component's updated props

Hi all! Thanks for the great package. We use it all over the place in our app here @ influxdata.

TLDR;

Should I be handling stateless components differently than in the example I provide?
Or, could react-onclickoutside be updated to respond to composed component prop changes?


I have a stateless component that looks (kinda) like this:

const DatabaseRow = ({
  retentionPolicy,
}) => {
const {name, duration, replication, isEditing, isDefault, isNew} = retentionPolicy
  return (
    <div>
      `${name}${duration}${replication}${isEditing}${isDefault}${isNew}`
    </div>
  )
}

export default onClickOutside(DatabaseRow)

Which gets rendered by another component which looks a bit like this:

database.retentionPolicies.map(retentionPolicy => {
  return (
    <DatabaseRow
      key={rp.id}
      handleClickOutside={() => onStopEditRetentionPolicy({database, retentionPolicy})}
     />
  )
})

When I updated retentionPolicy, I’d expect handleClickOutside to create a new closure around the updated retentionPolicy. So, when handleClickOutside fires onStopEditRetentionPolicy can operate on the most up to date retentionPolicy.

Here’s what I think is happening:

It looks like this line assigns the closure around onStopeEditRetentionPolicy (and its arguments) to the clickOutsideHandler variable on componentDidMount. It looks like that variable is not updated / reassigned when the Composed component’s props update. I worked around this by copying all of the code in componentDidMount into componentDidUpdate. Should I be handling stateless components differently? Or, could react-onclickoutside be updated to respond to composed component prop changes?

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 4
  • Comments: 17 (8 by maintainers)

Commits related to this issue

Most upvoted comments

Problem is that the actual handler is generated only in componentDidMount. So naturally if you change props later it wont get updated.

Fix should be quite straightforward, just wondering how to tackle this at code level. I think the best way is to compare with shallow equal all props on which the handler can depend in some lifecycle method and regenerate it if needed (+ ofc detach the old one and attach the new one). WDYT @Pomax ? I can provide a PR if we establish how this should be done.