Skip to content

Instantly share code, notes, and snippets.

@mjackson
Last active January 16, 2017 02:11
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mjackson/083624acf6f78fb4d8cd to your computer and use it in GitHub Desktop.
Save mjackson/083624acf6f78fb4d8cd to your computer and use it in GitHub Desktop.
Make window.scrollTo declarative using a <WindowScrollTo> React component
import React from 'react'
import warning from 'warning'
const { number, object } = React.PropTypes
const WindowScrollTo = React.createClass({
contextTypes: {
windowScrollTo: object
},
childContextTypes: {
windowScrollTo: object.isRequired
},
getChildContext() {
return {
windowScrollTo: this
}
},
propTypes: {
x: number,
y: number
},
updateScrollPosition() {
let { x, y } = this.props
if (typeof x !== 'number') {
if (typeof y !== 'number')
return // Nothing to do
x = window.scrollX // Preserve existing window.scrollX
}
if (typeof y !== 'number')
y = window.scrollY // Preserve existing window.scrollY
window.scrollTo(x, y)
},
componentWillMount() {
warning(
this.context.windowScrollTo == null,
'You should not render more than one <WindowScrollTo> in a tree; ' +
'they will most likely conflict'
)
},
componentDidMount() {
this.updateScrollPosition()
},
componentDidUpdate(prevProps) {
if (prevProps.x !== this.props.x || prevProps.y !== this.props.y)
this.updateScrollPosition()
},
render() {
return null
}
})
@Fenntasy
Copy link

Is it just an example or can you find an example to use this?
I can't get my head around it. Usually, the need for window.scrollTo is relative to a specific component.

But still, if you have a use case for that, it could be useful.

@hew
Copy link

hew commented Mar 5, 2016

@Fenntasy,

You might use it something like this:

{ someCondition &&  
  <WindowScrollTo x={44} y={44} > 
    <div class="beep">I like hummus</div> 
  </WindowScrollTo> 
}
<div class="beep">I like hummus</div> 

Or you might tweak updateScrollPosition() with a general truthy check such that you could use it this way:

<WindowScrollTo x={44} y={44} shouldScroll={someCondition}> 
  <div class="beep">I like hummus</div> 
</WindowScrollTo> 

@hew
Copy link

hew commented Mar 5, 2016

Actually, without touching the original, you could even do this:

render () {

  const shouldScroll = someCondition ? 44 : NaN

  return (
    <WindowScrollTo x={shouldScroll} y={false} > 
       <div class="beep">I like hummus</div> 
     </WindowScrollTo> 
   )
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment