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

Feature/bounds #109

Merged
merged 2 commits into from
Jul 13, 2016
Merged
Show file tree
Hide file tree
Changes from 1 commit
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: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@
"author": "Brigade Engineering",
"license": "MIT",
"peerDependencies": {
"react": "^0.14.0 || ^15.0.0",
"react-dom": "^0.14.0 || ^15.0.0"
"react": "^0.14.0 || ^15.0.0"
},
"devDependencies": {
"babel": "^6.0.0",
Expand Down
16 changes: 10 additions & 6 deletions src/waypoint.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, { PropTypes } from 'react';
import ReactDOM from 'react-dom';

const POSITIONS = {
above: 'above',
Expand Down Expand Up @@ -54,6 +53,12 @@ function debugLog() {
* Calls a function when you scroll to the element.
*/
export default class Waypoint extends React.Component {
constructor() {
super();

this.refElement = (e) => this._ref = e;
}

componentWillMount() {
if (this.props.scrollableParent) { // eslint-disable-line react/prop-types
throw new Error('The `scrollableParent` prop has changed name ' +
Expand Down Expand Up @@ -113,7 +118,7 @@ export default class Waypoint extends React.Component {
return this.props.scrollableAncestor;
}

let node = ReactDOM.findDOMNode(this);
let node = this._ref;

while (node.parentNode) {
node = node.parentNode;
Expand Down Expand Up @@ -264,16 +269,15 @@ export default class Waypoint extends React.Component {
}

_getBounds() {
const waypointTop = ReactDOM.findDOMNode(this).getBoundingClientRect().top;
const waypointTop = this._ref.getBoundingClientRect().top;
let contextHeight;
let contextScrollTop;
if (this.scrollableAncestor === window) {
contextHeight = window.innerHeight;
contextScrollTop = 0;
} else {
contextHeight = this.scrollableAncestor.offsetHeight;
contextScrollTop = ReactDOM
.findDOMNode(this.scrollableAncestor)
contextScrollTop = this.scrollableAncestor
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth noting that this would be a breaking change

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand how this changes anything.
this.scrollableAncestor is a dom element so
ReactDOM.findDOMNode(this.scrollableAncestor) === this.scrollableAncestor

Copy link
Collaborator

@jamesplease jamesplease Jul 13, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, you're right. I was thinking that passing a component instance in as a scrollableAncestor would work (by leveraging findDOMNode), but I took another look at the source and saw that it would error earlier on in the code.

Ignore me! 🙈

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch!

.getBoundingClientRect().top;
}
if (this.props.debug) {
Expand Down Expand Up @@ -328,7 +332,7 @@ export default class Waypoint extends React.Component {
render() {
// We need an element that we can locate in the DOM to determine where it is
// rendered relative to the top of its context.
return <span style={{fontSize: 0}} />;
return <span ref={this.refElement} style={{fontSize: 0}} />;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for not using an anonymous function to handle the ref setting.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine, but I'm not sure it really makes much difference either way. My preference would be to use the arrow function here to reduce unnecessary indirection.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've never been able to prove from looking at the react source that an anonymous function on ref does or does not cause a the virtual DOM to be synced to the real DOM. You cannot inspect ref in shouldComponentUpdate which would imply to me that is does not cause it to be synced but I was never able to definitively determine that.

eslint if configured to prohibit anonymous functions in render will still complain if it is ref, but maybe it is just too strict.

}
}

Expand Down