Skip to content

Commit

Permalink
Merge pull request #173 from sag1v/stop-autoplay-onunmount
Browse files Browse the repository at this point in the history
prevent state updates when unmounted
  • Loading branch information
sag1v authored Apr 14, 2021
2 parents 9769fcc + f7a9033 commit 2e3de6f
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 24 deletions.
52 changes: 37 additions & 15 deletions demoApp/src/DemoApp.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useState, useRef } from "react";
import Carousel from "react-elastic-carousel";
import React, { useState, useRef, useEffect } from "react";
import Carousel from "../../src/react-elastic-carousel/components/Carousel";
import styled from "styled-components";

const Item = styled.div`
Expand All @@ -16,7 +16,6 @@ const Item = styled.div`
const Layout = styled.div`
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100vh;
`;
Expand Down Expand Up @@ -47,8 +46,12 @@ const CheckBox = ({ label, onToggle, ...rest }) => {
);
};

const serverItems = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

const DemoApp = () => {
const [items, setItems] = useState([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
const [show, setShow] = useState(true);
const [enableAutoPlay, setEnableAutoPlay] = useState(false);
const [items, setItems] = useState([]);
const [itemsToShow, setItemsToShow] = useState(3);
const [showArrows, setShowArrows] = useState(true);
const [pagination, setPagination] = useState(true);
Expand All @@ -68,9 +71,20 @@ const DemoApp = () => {

const goTo = ({ target }) => carouselRef.current.goTo(Number(target.value));

useEffect(() => {
setTimeout(() => {
setItems(serverItems);
}, 2500);
}, []);

return (
<Layout>
<ControlsLayout>
<StyledControlFields>
<button onClick={() => setShow((o) => !o)}>
{`${show ? "Hide" : "Show"} Carousel`}
</button>
</StyledControlFields>
<StyledControlFields>
<button onClick={addItem}>Add Item</button>
<button onClick={removeItem}>Remove Item</button>
Expand Down Expand Up @@ -102,18 +116,26 @@ const DemoApp = () => {
checked={verticalMode}
onToggle={setVerticalMode}
/>
<CheckBox
label="Auto Play"
checked={enableAutoPlay}
onToggle={setEnableAutoPlay}
/>
</ControlsLayout>
<Carousel
ref={carouselRef}
verticalMode={verticalMode}
itemsToShow={itemsToShow}
showArrows={showArrows}
pagination={pagination}
>
{items.map((item) => (
<Item key={item}>{item}</Item>
))}
</Carousel>
{show && (
<Carousel
enableAutoPlay={enableAutoPlay}
ref={carouselRef}
verticalMode={verticalMode}
itemsToShow={itemsToShow}
showArrows={showArrows}
pagination={pagination}
>
{items.map((item) => (
<Item key={item}>{item}</Item>
))}
</Carousel>
)}
</Layout>
);
};
Expand Down
9 changes: 7 additions & 2 deletions demoApp/src/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import React from "react";
import ReactDOM from "react-dom";
import DemoApp from './DemoApp';
import DemoApp from "./DemoApp";

ReactDOM.render(<DemoApp />, document.getElementById("app"));
ReactDOM.render(
<React.StrictMode>
<DemoApp />
</React.StrictMode>,
document.getElementById("app")
);
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-elastic-carousel",
"version": "0.11.4",
"version": "0.11.5-beta.3",
"description": "A flexible and responsive carousel component for react",
"author": "sag1v (Sagiv Ben Giat)",
"license": "MIT",
Expand All @@ -25,7 +25,6 @@
"test:watch": "react-scripts test --env=jsdom",
"prebuild": "yarn run lint:fix",
"build": "rollup -c",
"prepare": "yarn run build",
"build-doc": "docz build",
"deploy-doc": "gh-pages -d demo"
},
Expand Down
27 changes: 22 additions & 5 deletions src/react-elastic-carousel/components/Carousel.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { pipe, noop, cssPrefix, numberToArray } from "../utils/helpers";
import { Pagination } from "./Pagination";

class Carousel extends React.Component {
isComponentMounted = false;
state = {
rootHeight: 0,
childHeight: 0,
Expand All @@ -32,6 +33,7 @@ class Carousel extends React.Component {
};

componentDidMount() {
this.isComponentMounted = true;
this.initResizeObserver();
this.updateActivePage();
this.setPages();
Expand Down Expand Up @@ -89,6 +91,8 @@ class Carousel extends React.Component {
}

componentWillUnmount() {
this.isComponentMounted = false;
this.removeAutoPlay();
this.unSubscribeObserver();
}

Expand Down Expand Up @@ -125,9 +129,11 @@ class Carousel extends React.Component {
setAutoPlay = () => {
const { autoPlaySpeed } = this.getDerivedPropsFromBreakPoint();
this.autoPlayIntervalId = setInterval(() => {
const { transitioning } = this.state;
if (!transitioning) {
this.slideNext();
if (this.isComponentMounted) {
const { transitioning } = this.state;
if (!transitioning) {
this.slideNext();
}
}
}, autoPlaySpeed);
};
Expand Down Expand Up @@ -200,7 +206,11 @@ class Carousel extends React.Component {
// go back from 0ms to whatever set by the user
// We were at 0ms because we wanted to disable animation on resize
// see https://github.com/sag1v/react-elastic-carousel/issues/94
window.requestAnimationFrame(() => this.setState({ transitionMs }));
window.requestAnimationFrame(() => {
if (this.isComponentMounted) {
this.setState({ transitionMs });
}
});
return {
sliderPosition,
activeIndex: newActiveIndex < 0 ? 0 : newActiveIndex
Expand All @@ -209,6 +219,10 @@ class Carousel extends React.Component {
};

onSliderResize = sliderNode => {
if (!this.isComponentMounted) {
return;
}

const {
verticalMode,
children,
Expand Down Expand Up @@ -271,7 +285,10 @@ class Carousel extends React.Component {
const containerWidth =
newSliderContainerWidth - (initialVerticalMode ? 0 : outerSpacing * 2);

if (this.state.sliderContainerWidth === newSliderContainerWidth) {
if (
!this.isComponentMounted ||
this.state.sliderContainerWidth === newSliderContainerWidth
) {
// prevent infinite loop
return;
}
Expand Down

0 comments on commit 2e3de6f

Please sign in to comment.