Skip to content
This repository was archived by the owner on Jan 19, 2023. It is now read-only.

Commit 3f602ca

Browse files
committed
Fix bug where using hotkeys would unload cached images
Apparently the key handlers being attached to the document made them fire in such a way that an extra render would occur. That was briefly interrupting the persistence of the left and right image elements, encouraging the garbage collector to clean up the image cache.
1 parent 7911314 commit 3f602ca

File tree

1 file changed

+35
-14
lines changed

1 file changed

+35
-14
lines changed

src/react-image-lightbox.js

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -128,17 +128,35 @@ class ReactImageLightbox extends Component {
128128
}
129129

130130
componentDidMount() {
131+
this.mounted = true;
131132
this.attachListeners();
132133

133134
this.loadAllImages();
134135
}
135136

136137
componentWillReceiveProps(nextProps) {
137-
const sourcesChanged = this.getSrcTypes().some(srcType =>
138-
this.props[srcType.name] !== nextProps[srcType.name]
139-
);
138+
// Iterate through the source types for prevProps and nextProps to
139+
// determine if any of the sources changed
140+
let sourcesChanged = false;
141+
const prevSrcDict = {};
142+
const nextSrcDict = {};
143+
this.getSrcTypes().forEach(srcType => {
144+
if (this.props[srcType.name] !== nextProps[srcType.name]) {
145+
sourcesChanged = true;
146+
147+
prevSrcDict[this.props[srcType.name]] = true;
148+
nextSrcDict[nextProps[srcType.name]] = true;
149+
}
150+
});
140151

141152
if (sourcesChanged || this.moveRequested) {
153+
// Reset the loaded state for images not rendered next
154+
Object.keys(prevSrcDict).forEach(prevSrc => {
155+
if (!(prevSrc in nextSrcDict) && (prevSrc in this.imageCache)) {
156+
this.imageCache[prevSrc].loaded = false;
157+
}
158+
});
159+
142160
this.moveRequested = false;
143161

144162
// Load any new images
@@ -147,14 +165,13 @@ class ReactImageLightbox extends Component {
147165
}
148166

149167
componentWillUnmount() {
168+
this.mounted = false;
150169
this.detachListeners();
151170
}
152171

153172
// Attach key and mouse input events
154173
attachListeners() {
155174
if (!this.listenersAttached) {
156-
document.addEventListener('keydown', this.handleKeyInput);
157-
document.addEventListener('keyup', this.handleKeyInput);
158175
window.addEventListener('resize', this.handleWindowResize);
159176
window.addEventListener('mouseup', this.handleMouseUp);
160177
window.addEventListener('touchend', this.handleMouseUp);
@@ -232,8 +249,6 @@ class ReactImageLightbox extends Component {
232249
// Detach key and mouse input events
233250
detachListeners() {
234251
if (this.listenersAttached) {
235-
document.removeEventListener('keydown', this.handleKeyInput);
236-
document.removeEventListener('keyup', this.handleKeyInput);
237252
window.removeEventListener('resize', this.handleWindowResize);
238253
window.removeEventListener('mouseup', this.handleMouseUp);
239254
window.removeEventListener('touchend', this.handleMouseUp);
@@ -639,7 +654,7 @@ class ReactImageLightbox extends Component {
639654
return this.state.shouldAnimate || this.state.isClosing;
640655
}
641656

642-
// Load image from src and call callback with image width and height on load
657+
// Check if image is loaded
643658
isImageLoaded(imageSrc) {
644659
return imageSrc && (imageSrc in this.imageCache) && this.imageCache[imageSrc].loaded;
645660
}
@@ -686,7 +701,8 @@ class ReactImageLightbox extends Component {
686701
}
687702

688703
// Don't rerender if the src is not the same as when the load started
689-
if (this.props[srcType] !== imageSrc) {
704+
// or if the component has unmounted
705+
if (this.props[srcType] !== imageSrc || !this.mounted) {
690706
return;
691707
}
692708

@@ -940,13 +956,9 @@ class ReactImageLightbox extends Component {
940956
isOpen
941957
onRequestClose={noop}
942958
style={modalStyle}
959+
onAfterOpen={() => this.outerEl && this.outerEl.focus()} // Focus on the div with key handlers
943960
>
944961
<div // Floating modal with closing animations
945-
onWheel={this.handleOuterMousewheel}
946-
onMouseMove={this.handleOuterMouseMove}
947-
onMouseDown={this.handleOuterMouseDown}
948-
onTouchStart={this.handleOuterTouchStart}
949-
onTouchMove={this.handleOuterTouchMove}
950962
className={`outer ${styles.outer} ${styles.outerAnimating}` +
951963
(this.state.isClosing ? ` closing ${styles.outerClosing}` : '')
952964
}
@@ -955,6 +967,15 @@ class ReactImageLightbox extends Component {
955967
animationDuration: `${this.props.animationDuration}ms`,
956968
animationDirection: this.state.isClosing ? 'normal' : 'reverse',
957969
}}
970+
ref={el => { this.outerEl = el; }}
971+
onWheel={this.handleOuterMousewheel}
972+
onMouseMove={this.handleOuterMouseMove}
973+
onMouseDown={this.handleOuterMouseDown}
974+
onTouchStart={this.handleOuterTouchStart}
975+
onTouchMove={this.handleOuterTouchMove}
976+
tabIndex="-1" // Enables key handlers on div
977+
onKeyDown={this.handleKeyInput}
978+
onKeyUp={this.handleKeyInput}
958979
>
959980

960981
<div // Image holder

0 commit comments

Comments
 (0)