-1

I am implementing a crop feature with React. When the user right clicks, a context menu appears. In the context menu, a user can select crop item. When a user selects crop, cropping gets activated. Now, I want to close the cropping state when the user clicks outside of that division. How do I have to do react way without DOM manipulation? Or should I have to use DOM manipulations such as add EventListener & removeListener? What are the cons of using DOM access here? Please let me know this thoroughly since this is going to be implemented in many of the features I am going to develop. For example, the context menu I was talking about, or the dropdown menu.

Here is an example for the reference - Sandbox. Now, when the user clicks outside of ReactCrop component, I want to close the crop through react way.

I don't want to go ahead with document.addEventListener or removeListener.

vam
  • 492
  • 7
  • 17

1 Answers1

1

If you really, really don't want to attach dom events to your components, you can add a 'dismisser' component behind the Crop component and handle the reset there.

const Dismisser = ({ onClick }) => <div onClick={onClick} style={{
  position: 'fixed',
  top: 0, left: 0, right: 0, bottom: 0,
  zIndex: 100,
}} />

In your component:

{src && (
  <React.Fragment>
  <div style={{position: 'relative', zIndex: 200}}>
    <ReactCrop
      src={src}
      crop={crop}
      ...
    />
  </div>
  <Dismisser onClick={this.resetCrop} />
  </React.Fragment>
)}

Codesandbox

I'd say that's a bit more 'React-y' since the responsiblity of reseting the crop is delegated to another component. However it'll give you trouble when your Crop component is behind other Dom element, z-index wise. You can get over it by using portal, but it'll start to get complex.

I think attaching DOM event is a valid solution here (as long as you remember to remove them). It's simpler, plus it's not like you're directly manipulating a dom node using data outside of React's flow, which most of the time is the real bad case.

Derek Nguyen
  • 11,294
  • 1
  • 40
  • 64