Skip to content

Commit

Permalink
Merge pull request #490 from ardeois/fix/unmount-state-issue
Browse files Browse the repository at this point in the history
fix: state leak when component is unmounted
  • Loading branch information
hudovisk authored Apr 26, 2022
2 parents d09960e + 0a1e06a commit 01921bd
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
6 changes: 5 additions & 1 deletion src/Experiment.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import PropTypes from "prop-types";
import OptimizeContext from "./OptimizeContext";

class Experiment extends React.Component {
isUnmounted = false;
state = {
variant: null,
};
Expand Down Expand Up @@ -48,7 +49,9 @@ class Experiment extends React.Component {
);
const oldHideEnd = window.dataLayer.hide.end;
window.dataLayer.hide.end = () => {
this.updateVariantFromGlobalState();
if (!this.isUnmounted) {
this.updateVariantFromGlobalState();
}
oldHideEnd && oldHideEnd();
};

Expand Down Expand Up @@ -82,6 +85,7 @@ class Experiment extends React.Component {

componentWillUnmount() {
clearTimeout(this.updateVariantTimeout);
this.isUnmounted = true;
typeof window !== "undefined" &&
window.gtag &&
window.gtag("event", "optimize.callback", {
Expand Down
32 changes: 32 additions & 0 deletions test/specs/experiment.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ import sinon from "sinon";
import { Experiment } from "../../src";

describe("experiment", () => {
afterEach(() => {
delete window.google_optimize;
delete window.dataLayer;
});

it("should require experiment id", () => {
expect(() => shallow(<Experiment />)).to.throw();
});
Expand Down Expand Up @@ -50,5 +55,32 @@ describe("experiment", () => {

expect(wrapper.find(Loader)).to.have.lengthOf(1);
});

it("should update variant after optimize is loaded", () => {
delete window.dataLayer;
const wrapper = shallow(<Experiment id="abc" />);

expect(wrapper.state("variant")).to.be.equal(null);

// Load google optimize
window.google_optimize = { get: sinon.stub().returns("2") };
window.dataLayer.hide.end();

expect(wrapper.state("variant")).to.be.equal("2");
});

it("should not update variant after optimize is loaded if component was unmounted", () => {
delete window.dataLayer;
const wrapper = shallow(<Experiment id="abc" />);

expect(wrapper.state("variant")).to.be.equal(null);

wrapper.unmount();
// Load google optimize
window.google_optimize = { get: sinon.stub().returns("2") };

// If component state is updated while component is unmounted, this call will crash
window.dataLayer.hide.end();
});
});
});

0 comments on commit 01921bd

Please sign in to comment.