Skip to content

Commit 99adf6f

Browse files
authored
Merge pull request #2331 from akiran/fix-2315
Fixed #2315
2 parents 2420174 + 02629d5 commit 99adf6f

File tree

7 files changed

+84
-10
lines changed

7 files changed

+84
-10
lines changed

.prettierrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
trailingComma: none
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Test fix of #2315: Slider crashing after a state change in parent component
2+
import React from "react";
3+
import { render, fireEvent } from "@testing-library/react";
4+
5+
import { getCurrentSlideContent, getSlidesCount } from "../../test-utils";
6+
import { GenericSliderComponent } from "../TestComponents";
7+
8+
function TestSlider() {
9+
const [count, setCount] = React.useState();
10+
11+
return (
12+
<div>
13+
<button className="increment-button" onClick={() => setCount(count + 1)}>
14+
Increment {count}
15+
</button>
16+
<GenericSliderComponent slidesCount={6} settings={{ count }} />
17+
</div>
18+
);
19+
}
20+
21+
describe("State change in parent component of slider", () => {
22+
it("Slider shoud work afer clicking on Increment button", function() {
23+
const { container } = render(<TestSlider />);
24+
fireEvent(
25+
container.getElementsByClassName("increment-button")[0],
26+
new MouseEvent("click", {
27+
bubbles: true,
28+
cancelable: true
29+
})
30+
);
31+
// Throws an error "Maximum update depth exceeded." if the bug exists
32+
expect(getCurrentSlideContent(container)).toEqual("1");
33+
expect(getSlidesCount(container)).toEqual(13);
34+
});
35+
});
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { filterSettings } from "../../src/utils/innerSliderUtils";
2+
3+
describe("filterSettings", () => {
4+
it("returns empty object if there are no valid settings", () => {
5+
expect(filterSettings({})).toEqual({});
6+
expect(filterSettings({ age: 10 })).toEqual({});
7+
});
8+
it("return an object with valid settings and omits extra properties", () => {
9+
expect(filterSettings({ arrows: true, dots: true })).toEqual({
10+
arrows: true,
11+
dots: true
12+
});
13+
expect(filterSettings({ arrows: true, dots: true, age: 10 })).toEqual({
14+
arrows: true,
15+
dots: true
16+
});
17+
});
18+
});

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
"gen": "node examples/scripts/generateExampleConfigs.js && node examples/scripts/generateExamples.js && xdg-open docs/jquery.html",
1919
"precommit": "lint-staged",
2020
"test": "jest",
21-
"test-watch": "jest --watch"
21+
"test-watch": "jest --watch",
22+
"clear-jest": "jest --clearCache"
2223
},
2324
"author": "Kiran Abburi",
2425
"license": "MIT",

src/inner-slider.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,8 @@ export class InnerSlider extends React.Component {
134134
}
135135
if (
136136
typeof prevProps[key] === "object" ||
137-
typeof prevProps[key] === "function"
137+
typeof prevProps[key] === "function" ||
138+
isNaN(prevProps[key])
138139
) {
139140
continue;
140141
}

src/slider.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import React from "react";
44
import { InnerSlider } from "./inner-slider";
55
import json2mq from "json2mq";
66
import defaultProps from "./default-props";
7-
import { canUseDOM } from "./utils/innerSliderUtils";
7+
import { canUseDOM, filterSettings } from "./utils/innerSliderUtils";
88
const enquire = canUseDOM() && require("enquire.js");
99

1010
export default class Slider extends React.Component {
@@ -198,14 +198,17 @@ export default class Slider extends React.Component {
198198
if (settings === "unslick") {
199199
const className = "regular slider " + (this.props.className || "");
200200
return <div className={className}>{children}</div>;
201-
} else if (newChildren.length <= settings.slidesToShow && !settings.infinite) {
201+
} else if (
202+
newChildren.length <= settings.slidesToShow &&
203+
!settings.infinite
204+
) {
202205
settings.unslick = true;
203206
}
204207
return (
205208
<InnerSlider
206209
style={this.props.style}
207210
ref={this.innerSliderRefHandler}
208-
{...settings}
211+
{...filterSettings(settings)}
209212
>
210213
{newChildren}
211214
</InnerSlider>

src/utils/innerSliderUtils.js

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
import React from "react";
2+
import defaultProps from "../default-props";
23

34
export function clamp(number, lowerBound, upperBound) {
45
return Math.max(lowerBound, Math.min(number, upperBound));
56
}
67

78
export const safePreventDefault = event => {
89
const passiveEvents = ["onTouchStart", "onTouchMove", "onWheel"];
9-
if(!passiveEvents.includes(event._reactName)) {
10+
if (!passiveEvents.includes(event._reactName)) {
1011
event.preventDefault();
1112
}
12-
}
13+
};
1314

1415
export const getOnDemandLazySlides = spec => {
1516
let onDemandSlides = [];
@@ -386,9 +387,12 @@ export const swipeMove = (e, spec) => {
386387
let touchSwipeLength = touchObject.swipeLength;
387388
if (!infinite) {
388389
if (
389-
(currentSlide === 0 && (swipeDirection === "right" || swipeDirection === "down")) ||
390-
(currentSlide + 1 >= dotCount && (swipeDirection === "left" || swipeDirection === "up")) ||
391-
(!canGoNext(spec) && (swipeDirection === "left" || swipeDirection === "up"))
390+
(currentSlide === 0 &&
391+
(swipeDirection === "right" || swipeDirection === "down")) ||
392+
(currentSlide + 1 >= dotCount &&
393+
(swipeDirection === "left" || swipeDirection === "up")) ||
394+
(!canGoNext(spec) &&
395+
(swipeDirection === "left" || swipeDirection === "up"))
392396
) {
393397
touchSwipeLength = touchObject.swipeLength * edgeFriction;
394398
if (edgeDragged === false && onEdge) {
@@ -849,3 +853,14 @@ export const canUseDOM = () =>
849853
window.document &&
850854
window.document.createElement
851855
);
856+
857+
export const validSettings = Object.keys(defaultProps);
858+
859+
export function filterSettings(settings) {
860+
return validSettings.reduce((acc, settingName) => {
861+
if (settings.hasOwnProperty(settingName)) {
862+
acc[settingName] = settings[settingName];
863+
}
864+
return acc;
865+
}, {});
866+
}

0 commit comments

Comments
 (0)