Skip to content
This repository was archived by the owner on Apr 15, 2025. It is now read-only.

Commit b582fe6

Browse files
committed
Patched Issue #2 setState() warning on unmount.
1 parent 20feea1 commit b582fe6

File tree

4 files changed

+110
-8
lines changed

4 files changed

+110
-8
lines changed

lib/imageCacheHoc.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import FileSystemFactory, { FileSystem } from '../lib/FileSystem';
2121
import traverse from 'traverse';
2222
import validator from 'validator';
2323
import uuid from 'react-native-uuid';
24+
import makeCancelable from 'makecancelable';
2425

2526
export default function imageCacheHoc(Image, options = {}) {
2627

@@ -144,12 +145,14 @@ export default function imageCacheHoc(Image, options = {}) {
144145
FileSystem.lockCacheFile(fileName, this.componentId);
145146

146147
// Check local fs for file, fallback to network and write file to disk if local file not found.
148+
// This must be cancelable in case component is unmounted before request completes.
147149
let permanent = this.props.permanent ? true : false;
148150

149-
this.fileSystem.getLocalFilePathFromUrl(traverse(this.props).get(['source', 'uri']), permanent)
150-
.then( localFilePath => {
151-
this.setState({ localFilePath });
152-
});
151+
this.cancelLocalFilePathRequest = makeCancelable(
152+
this.fileSystem.getLocalFilePathFromUrl(traverse(this.props).get(['source', 'uri']), permanent),
153+
localFilePath => this.setState({ localFilePath }),
154+
error => console.error(error) // eslint-disable-line no-console
155+
);
153156

154157
}
155158

@@ -159,6 +162,9 @@ export default function imageCacheHoc(Image, options = {}) {
159162
let fileName = this.fileSystem.getFileNameFromUrl(traverse(this.props).get(['source', 'uri']));
160163
FileSystem.unlockCacheFile(fileName, this.componentId);
161164

165+
// Cancel pending setState() actions.
166+
this.cancelLocalFilePathRequest();
167+
162168
}
163169

164170
render() {

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@
4040
"react": "^16.0.0",
4141
"react-native": "^0.50.1",
4242
"react-test-renderer": "^16.0.0",
43-
"should": "^13.1.2"
43+
"should": "^13.1.2",
44+
"should-sinon": "^0.0.6",
45+
"sinon": "^4.1.2"
4446
},
4547
"jest": {
4648
"preset": "react-native",
@@ -51,6 +53,7 @@
5153
"dependencies": {
5254
"buffer": "^5.0.8",
5355
"crypto-js": "^3.1.9-1",
56+
"makecancelable": "^1.0.0",
5457
"path": "^0.12.7",
5558
"prop-types": "^15.6.0",
5659
"react-native-fetch-blob": "0.10.8",

tests/CacheableImage.test.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11

22
// Define globals for eslint.
3-
/* global describe it require */
3+
/* global describe it require jest */
44

55
// Load dependencies
66
import should from 'should'; // eslint-disable-line no-unused-vars
77
import { mockData } from './mockData';
88
import imageCacheHoc from '../lib/imageCacheHoc';
99
import { Image } from 'react-native';
10+
import sinon from 'sinon';
11+
import 'should-sinon';
1012

1113
describe('CacheableImage', function() {
1214

@@ -260,6 +262,27 @@ describe('CacheableImage', function() {
260262

261263
});
262264

265+
it('setState() actions on component mount should create cancelable functions and use on unmount.', () => {
266+
267+
// Set up mocks
268+
const FileSystem = require('../lib/FileSystem').default;
269+
FileSystem.prototype.getLocalFilePathFromUrl = jest.fn();
270+
FileSystem.prototype.getLocalFilePathFromUrl.mockReturnValue(new Promise((resolve) => {
271+
resolve(mockData.basePath + '/react-native-image-cache-hoc/permanent/cd7d2199cd8e088cdfd9c99fc6359666adc36289.png');
272+
}));
273+
274+
const CacheableImage = imageCacheHoc(Image);
275+
const cacheableImage = new CacheableImage(mockData.mockCacheableImageProps);
276+
277+
// Mount and unmount
278+
cacheableImage.componentDidMount();
279+
cacheableImage.cancelLocalFilePathRequest(); // Call it once manually to actually cancel local file path request
280+
cacheableImage.cancelLocalFilePathRequest = sinon.spy(); // Set up a spy to make sure it gets called in componentWillUnmount().
281+
cacheableImage.componentWillUnmount();
282+
cacheableImage.cancelLocalFilePathRequest.should.be.calledOnce();
283+
284+
});
285+
263286
it('#render with valid props does not throw an error.', () => {
264287

265288
const CacheableImage = imageCacheHoc(Image);

yarn.lock

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1450,7 +1450,7 @@ detect-indent@^4.0.0:
14501450
dependencies:
14511451
repeating "^2.0.0"
14521452

1453-
diff@^3.2.0:
1453+
diff@^3.1.0, diff@^3.2.0:
14541454
version "3.4.0"
14551455
resolved "https://registry.yarnpkg.com/diff/-/diff-3.4.0.tgz#b1d85507daf3964828de54b37d0d73ba67dda56c"
14561456

@@ -1884,6 +1884,12 @@ form-data@~2.3.1:
18841884
combined-stream "^1.0.5"
18851885
mime-types "^2.1.12"
18861886

1887+
[email protected], formatio@^1.2.0:
1888+
version "1.2.0"
1889+
resolved "https://registry.yarnpkg.com/formatio/-/formatio-1.2.0.tgz#f3b2167d9068c4698a8d51f4f760a39a54d818eb"
1890+
dependencies:
1891+
samsam "1.x"
1892+
18871893
18881894
version "0.3.0"
18891895
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.3.0.tgz#651f838e22424e7566de161d8358caa199f83d4f"
@@ -2832,6 +2838,10 @@ jsx-ast-utils@^2.0.0:
28322838
dependencies:
28332839
array-includes "^3.0.3"
28342840

2841+
just-extend@^1.1.26:
2842+
version "1.1.27"
2843+
resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-1.1.27.tgz#ec6e79410ff914e472652abfa0e603c03d60e905"
2844+
28352845
kind-of@^3.0.2:
28362846
version "3.2.2"
28372847
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
@@ -2947,6 +2957,10 @@ lodash.escape@^3.0.0:
29472957
dependencies:
29482958
lodash._root "^3.0.0"
29492959

2960+
lodash.get@^4.4.2:
2961+
version "4.4.2"
2962+
resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
2963+
29502964
lodash.isarguments@^3.0.0:
29512965
version "3.1.0"
29522966
resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a"
@@ -3012,6 +3026,14 @@ log-driver@^1.2.5:
30123026
version "1.2.5"
30133027
resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.5.tgz#7ae4ec257302fd790d557cb10c97100d857b0056"
30143028

3029+
lolex@^1.6.0:
3030+
version "1.6.0"
3031+
resolved "https://registry.yarnpkg.com/lolex/-/lolex-1.6.0.tgz#3a9a0283452a47d7439e72731b9e07d7386e49f6"
3032+
3033+
lolex@^2.2.0:
3034+
version "2.3.0"
3035+
resolved "https://registry.yarnpkg.com/lolex/-/lolex-2.3.0.tgz#d6bad0f0aa5caebffcfebb09fb2caa89baaff51c"
3036+
30153037
longest@^1.0.1:
30163038
version "1.0.1"
30173039
resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097"
@@ -3033,6 +3055,10 @@ macos-release@^1.0.0:
30333055
version "1.1.0"
30343056
resolved "https://registry.yarnpkg.com/macos-release/-/macos-release-1.1.0.tgz#831945e29365b470aa8724b0ab36c8f8959d10fb"
30353057

3058+
makecancelable@^1.0.0:
3059+
version "1.0.0"
3060+
resolved "https://registry.yarnpkg.com/makecancelable/-/makecancelable-1.0.0.tgz#c7e2606e59db7a4bf8098ff5b52d7f13173499e5"
3061+
30363062
30373063
version "1.0.11"
30383064
resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c"
@@ -3243,6 +3269,16 @@ [email protected]:
32433269
version "0.6.1"
32443270
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9"
32453271

3272+
nise@^1.2.0:
3273+
version "1.2.0"
3274+
resolved "https://registry.yarnpkg.com/nise/-/nise-1.2.0.tgz#079d6cadbbcb12ba30e38f1c999f36ad4d6baa53"
3275+
dependencies:
3276+
formatio "^1.2.0"
3277+
just-extend "^1.1.26"
3278+
lolex "^1.6.0"
3279+
path-to-regexp "^1.7.0"
3280+
text-encoding "^0.6.4"
3281+
32463282
node-fetch@^1.0.1, node-fetch@^1.3.3:
32473283
version "1.7.3"
32483284
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
@@ -3501,6 +3537,12 @@ path-parse@^1.0.5:
35013537
version "1.0.5"
35023538
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1"
35033539

3540+
path-to-regexp@^1.7.0:
3541+
version "1.7.0"
3542+
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d"
3543+
dependencies:
3544+
isarray "0.0.1"
3545+
35043546
path-type@^1.0.0:
35053547
version "1.1.0"
35063548
resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441"
@@ -4063,6 +4105,10 @@ safe-buffer@~5.0.1:
40634105
version "5.0.1"
40644106
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.0.1.tgz#d263ca54696cd8a306b5ca6551e92de57918fbe7"
40654107

4108+
4109+
version "1.3.0"
4110+
resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.3.0.tgz#8d1d9350e25622da30de3e44ba692b5221ab7c50"
4111+
40664112
sane@^2.0.0:
40674113
version "2.2.0"
40684114
resolved "https://registry.yarnpkg.com/sane/-/sane-2.2.0.tgz#d6d2e2fcab00e3d283c93b912b7c3a20846f1d56"
@@ -4179,6 +4225,10 @@ should-format@^3.0.3:
41794225
should-type "^1.3.0"
41804226
should-type-adaptors "^1.0.1"
41814227

4228+
should-sinon@^0.0.6:
4229+
version "0.0.6"
4230+
resolved "https://registry.yarnpkg.com/should-sinon/-/should-sinon-0.0.6.tgz#be041a7c928f44ac9ccf5dc042d032618ce29f84"
4231+
41824232
should-type-adaptors@^1.0.1:
41834233
version "1.0.1"
41844234
resolved "https://registry.yarnpkg.com/should-type-adaptors/-/should-type-adaptors-1.0.1.tgz#efe5553cdf68cff66e5c5f51b712dc351c77beaa"
@@ -4216,6 +4266,18 @@ simple-plist@^0.2.1:
42164266
bplist-parser "0.1.1"
42174267
plist "2.0.1"
42184268

4269+
sinon@^4.1.2:
4270+
version "4.1.2"
4271+
resolved "https://registry.yarnpkg.com/sinon/-/sinon-4.1.2.tgz#65610521d926fb53742dd84cd599f0b89a82f440"
4272+
dependencies:
4273+
diff "^3.1.0"
4274+
formatio "1.2.0"
4275+
lodash.get "^4.4.2"
4276+
lolex "^2.2.0"
4277+
nise "^1.2.0"
4278+
supports-color "^4.4.0"
4279+
type-detect "^4.0.0"
4280+
42194281
slash@^1.0.0:
42204282
version "1.0.0"
42214283
resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
@@ -4396,7 +4458,7 @@ supports-color@^3.1.2:
43964458
dependencies:
43974459
has-flag "^1.0.0"
43984460

4399-
supports-color@^4.0.0:
4461+
supports-color@^4.0.0, supports-color@^4.4.0:
44004462
version "4.5.0"
44014463
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b"
44024464
dependencies:
@@ -4459,6 +4521,10 @@ test-exclude@^4.1.1:
44594521
read-pkg-up "^1.0.1"
44604522
require-main-filename "^1.0.1"
44614523

4524+
text-encoding@^0.6.4:
4525+
version "0.6.4"
4526+
resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19"
4527+
44624528
text-table@~0.2.0:
44634529
version "0.2.0"
44644530
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
@@ -4542,6 +4608,10 @@ type-check@~0.3.2:
45424608
dependencies:
45434609
prelude-ls "~1.1.2"
45444610

4611+
type-detect@^4.0.0:
4612+
version "4.0.5"
4613+
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.5.tgz#d70e5bc81db6de2a381bcaca0c6e0cbdc7635de2"
4614+
45454615
type-is@~1.6.6:
45464616
version "1.6.15"
45474617
resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.15.tgz#cab10fb4909e441c82842eafe1ad646c81804410"

0 commit comments

Comments
 (0)