Skip to content

Commit e903b1d

Browse files
authored
fix: stringify array thresholds (#404)
This fixes ensures Array thresholds are converted to a string when passed to the useCallback dependency array. This prevents infinite rerenders caused by arrays being recreated every render.
1 parent 891adf3 commit e903b1d

File tree

4 files changed

+1473
-1449
lines changed

4 files changed

+1473
-1449
lines changed

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -174,13 +174,13 @@
174174
"npm-run-all": "^4.1.5",
175175
"prettier": "^2.0.4",
176176
"prettier-plugin-pkg": "^0.8.0",
177-
"react": "^17.0.0-rc.1",
178-
"react-dom": "^17.0.0-rc.1",
177+
"react": "^17.0.0-rc.3",
178+
"react-dom": "^17.0.0-rc.3",
179179
"react-test-renderer": "^17.0.0-rc.1",
180180
"typescript": "^4.0.2"
181181
},
182182
"resolutions": {
183-
"react": "17.0.0-rc.1",
184-
"react-dom": "17.0.0-rc.1"
183+
"react": "17.0.0-rc.3",
184+
"react-dom": "17.0.0-rc.3"
185185
}
186186
}

src/__tests__/hooks.test.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,16 @@ test('should create a hook', () => {
4242
expect(instance.observe).toHaveBeenCalledWith(wrapper);
4343
});
4444

45+
test('should create a hook with array threshold', () => {
46+
const { getByTestId } = render(
47+
<HookComponent options={{ threshold: [0.1, 1] }} />,
48+
);
49+
const wrapper = getByTestId('wrapper');
50+
const instance = intersectionMockInstance(wrapper);
51+
52+
expect(instance.observe).toHaveBeenCalledWith(wrapper);
53+
});
54+
4555
test('should create a lazy hook', () => {
4656
const { getByTestId } = render(<LazyHookComponent />);
4757
const wrapper = getByTestId('wrapper');

src/useInView.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,19 @@ export function useInView({
5757
);
5858
}
5959
},
60-
[threshold, root, rootMargin, triggerOnce, skip, trackVisibility, delay],
60+
// We break the rule here, because we aren't including the actual `threshold` variable
61+
// eslint-disable-next-line react-hooks/exhaustive-deps
62+
[
63+
// If the threshold is an array, convert it to a string so it won't change between renders.
64+
// eslint-disable-next-line react-hooks/exhaustive-deps
65+
Array.isArray(threshold) ? threshold.toString() : threshold,
66+
root,
67+
rootMargin,
68+
triggerOnce,
69+
skip,
70+
trackVisibility,
71+
delay,
72+
],
6173
);
6274

6375
/* eslint-disable-next-line */

0 commit comments

Comments
 (0)