Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: refactored from findDOMNode to refs #476

Merged
merged 7 commits into from
Oct 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"Frederick Fogerty <frederick.fogerty@gmail.com> (https://github.com/frederickfogerty)",
"Max Kolyanov (https://github.com/maxkolyanov)",
"Sherwin Heydarbeygi <sherwin@imgix.com> (https://github.com/sherwinski)",
"Baldur Helgason <baldur.helgason@gmail.com> (https://github.com/baldurh)"
"Baldur Helgason <baldur.helgason@gmail.com> (https://github.com/baldurh)",
"Tanner Stirrat <tstirrat@gmail.com> (https://github.com/tstirrat15)"
],
"license": "ISC",
"bugs": {
Expand Down
55 changes: 35 additions & 20 deletions src/react-imgix.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import "./array-findindex";

import ReactDOM from "react-dom";
import React, { Component } from "react";
import PropTypes from "prop-types";

Expand Down Expand Up @@ -192,10 +191,14 @@ class ReactImgix extends Component {
onMounted: noop
};

componentDidMount = () => {
const node = ReactDOM.findDOMNode(this);
this.props.onMounted(node);
};
constructor(props) {
super(props);
this.imgRef = null;
}

componentDidMount() {
this.props.onMounted(this.imgRef);
}

render() {
const { disableSrcSet, type, width, height } = this.props;
Expand Down Expand Up @@ -233,7 +236,8 @@ class ReactImgix extends Component {
className: this.props.className,
width: width <= 1 ? null : width,
height: height <= 1 ? null : height,
[attributeConfig.src]: src
[attributeConfig.src]: src,
ref: el => (this.imgRef = el)
});
if (!disableSrcSet) {
childProps[attributeConfig.srcSet] = srcSet;
Expand Down Expand Up @@ -274,10 +278,15 @@ class PictureImpl extends Component {
onMounted: noop
};

componentDidMount = () => {
const node = ReactDOM.findDOMNode(this);
this.props.onMounted(node);
};
constructor(props) {
super(props);
this.pictureRef = null;
}

componentDidMount() {
this.props.onMounted(this.pictureRef);
}

render() {
const { children } = this.props;

Expand All @@ -291,10 +300,10 @@ class PictureImpl extends Component {
) || [];

/*
We need to make sure an <img /> or <Imgix /> is the last child so we look for one in children
a. if we find one, move it to the last entry if it's not already there
b. if we don't find one, warn the user as they probably want to pass one.
*/
We need to make sure an <img /> or <Imgix /> is the last child so we look for one in children
a. if we find one, move it to the last entry if it's not already there
b. if we don't find one, warn the user as they probably want to pass one.
*/

// look for an <img> or <ReactImgix type='img'> - at the bare minimum we have to have a single <img> element or else it will not work.
let imgIdx = _children.findIndex(
Expand All @@ -313,7 +322,7 @@ class PictureImpl extends Component {
_children.push(_children.splice(imgIdx, 1)[0]);
}

return <picture children={_children} />;
return <picture ref={el => (this.pictureRef = el)} children={_children} />;
}
}
PictureImpl.displayName = "ReactImgixPicture";
Expand All @@ -328,10 +337,15 @@ class SourceImpl extends Component {
onMounted: noop
};

componentDidMount = () => {
const node = ReactDOM.findDOMNode(this);
this.props.onMounted(node);
};
constructor(props) {
super(props);
this.sourceRef = null;
}

componentDidMount() {
this.props.onMounted(this.sourceRef);
}

render() {
const { disableSrcSet, width, height } = this.props;

Expand All @@ -353,7 +367,8 @@ class SourceImpl extends Component {
[attributeConfig.sizes]: this.props.sizes,
className: this.props.className,
width: width <= 1 ? null : width,
height: height <= 1 ? null : height
height: height <= 1 ? null : height,
ref: el => (this.sourceRef = el)
});

// inside of a <picture> element a <source> element ignores its src
Expand Down
70 changes: 16 additions & 54 deletions test/unit/react-imgix.test.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import sinon from "sinon";
import React from "react";
import ReactDOM from "react-dom";
import { shallow as enzymeShallow, mount } from "enzyme";
import PropTypes from "prop-types";
import { shallowUntilTarget } from "../helpers";
Expand Down Expand Up @@ -30,28 +29,6 @@ let sut, vdom, instance;
const EMPTY_IMAGE_SRC =
"data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=";

async function renderImageAndBreakInStages({
element,
mockImage = <img />,
afterFirstRender = async () => {},
afterSecondRender = async () => {}
}) {
sinon.stub(ReactDOM, "findDOMNode").callsFake(() => mockImage);

const sut = shallow(element);

await afterFirstRender(sut);

await sut.instance().componentDidMount();
sut.update();

await afterSecondRender(sut);

ReactDOM.findDOMNode.restore();

return sut;
}

let oldConsole, log;
beforeEach(() => {
oldConsole = global.console;
Expand Down Expand Up @@ -182,23 +159,18 @@ describe("When in default mode", () => {

describe("When in image mode", () => {
it("a callback passed through the onMounted prop should be called", () => {
const mockImage = <img />;
sinon.stub(ReactDOM, "findDOMNode").callsFake(() => mockImage);

const onMountedSpy = sinon.spy();
sut = shallow(
const sut = mount(
<Imgix
src={"https://mysource.imgix.net/demo.png"}
sizes="100vw"
onMounted={onMountedSpy}
/>,
__ReactImgixImpl,
{}
/>
);

sinon.assert.calledWith(onMountedSpy, mockImage);

ReactDOM.findDOMNode.restore();
expect(onMountedSpy.callCount).toEqual(1);
const onMountArg = onMountedSpy.lastCall.args[0];
expect(onMountArg).toBeInstanceOf(HTMLImageElement);
});
});

Expand Down Expand Up @@ -326,23 +298,18 @@ describe("When in <source> mode", () => {
});
});
it("a callback passed through the onMounted prop should be called", () => {
const mockImage = <source />;
sinon.stub(ReactDOM, "findDOMNode").callsFake(() => mockImage);

const onMountedSpy = sinon.spy();
sut = shallow(
const sut = mount(
<Source
src={"https://mysource.imgix.net/demo.png"}
sizes="100vw"
onMounted={onMountedSpy}
/>,
__SourceImpl,
{}
/>
);

sinon.assert.calledWith(onMountedSpy, mockImage);

ReactDOM.findDOMNode.restore();
expect(onMountedSpy.callCount).toEqual(1);
const onMountArg = onMountedSpy.lastCall.args[0];
expect(onMountArg).toBeInstanceOf(HTMLSourceElement);
});
});

Expand Down Expand Up @@ -460,21 +427,16 @@ describe("When in picture mode", () => {
});

it("a callback passed through the onMounted prop should be called", () => {
const mockImage = <source />;
sinon.stub(ReactDOM, "findDOMNode").callsFake(() => mockImage);

const onMountedSpy = sinon.spy();
sut = shallow(
<Picture onMounted={onMountedSpy}>
sut = mount(
<Picture onMounted={onMountedSpy} foo={1}>
<img />
</Picture>,
__PictureImpl,
{}
</Picture>
);

sinon.assert.calledWith(onMountedSpy, mockImage);

ReactDOM.findDOMNode.restore();
expect(onMountedSpy.callCount).toEqual(1);
const onMountArg = onMountedSpy.lastCall.args[0];
expect(onMountArg).toBeInstanceOf(HTMLPictureElement);
});
});

Expand Down