Skip to content

Commit 06fca52

Browse files
committed
Handle URI Prop Changes
1 parent 1597a57 commit 06fca52

File tree

1 file changed

+46
-24
lines changed

1 file changed

+46
-24
lines changed

lib/imageCacheHoc.js

Lines changed: 46 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -145,51 +145,73 @@ export default function imageCacheHoc(Image, options = {}) {
145145
// Track component mount status to avoid calling setState() on unmounted component.
146146
this._isMounted = true;
147147

148+
// Set url from source prop
149+
const url = traverse(this.props).get(['source', 'uri']);
150+
148151
// Add a cache lock to file with this name (prevents concurrent <CacheableImage> components from pruning a file with this name from cache).
149-
const fileName = await this.fileSystem.getFileNameFromUrl(traverse(this.props).get(['source', 'uri']));
152+
const fileName = await this.fileSystem.getFileNameFromUrl(url);
150153
FileSystem.lockCacheFile(fileName, this.componentId);
151154

152-
// Check local fs for file, fallback to network and write file to disk if local file not found.
153-
const permanent = this.props.permanent ? true : false;
154-
let localFilePath = null;
155-
try {
156-
localFilePath = await this.fileSystem.getLocalFilePathFromUrl(traverse(this.props).get(['source', 'uri']), permanent);
157-
} catch (error) {
158-
console.warn(error); // eslint-disable-line no-console
159-
}
160-
161-
// Check component is still mounted to avoid calling setState() on components that were quickly
162-
// mounted then unmounted before componentDidMount() finishes.
163-
// See: https://github.com/billmalarky/react-native-image-cache-hoc/issues/6#issuecomment-354490597
164-
if (this._isMounted && localFilePath) {
165-
this.setState({ localFilePath });
166-
}
155+
// Init the image cache logic
156+
await this._loadImage(url);
167157

168158
}
169159

160+
/**
161+
*
162+
* Enables caching logic to work if component source prop is updated (that is, the image url changes without mounting a new component).
163+
* See: https://github.com/billmalarky/react-native-image-cache-hoc/pull/15
164+
*
165+
* @param nextProps {Object} - Props that will be passed to component.
166+
*/
170167
async componentWillReceiveProps(nextProps) {
171-
const uri = traverse(this.props).get(['source', 'uri']);
172-
const nextUri = traverse(nextProps).get(['source', 'uri']);
173-
if (uri === nextUri) return;
174168

175-
const fileName = await this.fileSystem.getFileNameFromUrl(uri);
176-
const nextFileName = await this.fileSystem.getFileNameFromUrl(nextUri);
169+
// Set urls from source prop data
170+
const url = traverse(this.props).get(['source', 'uri']);
171+
const nextUrl = traverse(nextProps).get(['source', 'uri']);
172+
173+
// Do nothing if url has not changed.
174+
if (url === nextUrl) return;
175+
176+
// Remove component cache lock on old image file, and add cache lock to new image file.
177+
const fileName = await this.fileSystem.getFileNameFromUrl(url);
178+
const nextFileName = await this.fileSystem.getFileNameFromUrl(nextUrl);
177179

178180
FileSystem.unlockCacheFile(fileName, this.componentId);
179181
FileSystem.lockCacheFile(nextFileName, this.componentId);
180182

181-
const { permanent } = this.props;
183+
// Init the image cache logic
184+
await this._loadImage(nextUrl);
185+
186+
}
187+
188+
/**
189+
*
190+
* Executes the image download/cache logic and calls setState() with to re-render
191+
* component using local file path on completion.
192+
*
193+
* @param url {String} - The remote image url.
194+
* @private
195+
*/
196+
async _loadImage(url) {
197+
198+
// Check local fs for file, fallback to network and write file to disk if local file not found.
199+
const permanent = this.props.permanent ? true : false;
182200
let localFilePath = null;
183201
try {
184-
localFilePath = await this.fileSystem.getLocalFilePathFromUrl(nextUri, !!permanent);
202+
localFilePath = await this.fileSystem.getLocalFilePathFromUrl(url, permanent);
185203
} catch (error) {
186204
console.warn(error); // eslint-disable-line no-console
187205
}
188206

207+
// Check component is still mounted to avoid calling setState() on components that were quickly
208+
// mounted then unmounted before componentDidMount() finishes.
209+
// See: https://github.com/billmalarky/react-native-image-cache-hoc/issues/6#issuecomment-354490597
189210
if (this._isMounted && localFilePath) {
190211
this.setState({ localFilePath });
191212
}
192-
}
213+
214+
}
193215

194216
async componentWillUnmount() {
195217

0 commit comments

Comments
 (0)