Если вы действительно не хотите прикреплять события dom к своим компонентам, вы можете добавить компонент dismisser позади компонента Crop
и обработать сброс там.
const Dismisser = ({ onClick }) => <div onClick={onClick} style={{
position: 'fixed',
top: 0, left: 0, right: 0, bottom: 0,
zIndex: 100,
}} />
В вашем компоненте:
{src && (
<React.Fragment>
<div style={{position: 'relative', zIndex: 200}}>
<ReactCrop
src={src}
crop={crop}
...
/>
</div>
<Dismisser onClick={this.resetCrop} />
</React.Fragment>
)}
Codesandbox
Я бы сказал, что это немного больше «React-y», так как ответственность за переустановку культуры делегирована другому компоненту. Однако это создаст вам проблемы, когда ваш компонент Crop находится позади другого элемента Dom, z-index. Вы можете преодолеть это с помощью портала, но он станет сложным.
Я думаю, что присоединение DOM-события является допустимым решением (если вы не забыли их удалить). Это проще, плюс не похоже, что вы напрямую манипулируете dom-узлом, используя данные вне потока React, что в большинстве случаев является очень плохим случаем.