gilbox / react-spark-scroll

Scroll-based actions and animations for react
358 stars 48 forks source link

Isomorphic rendering support #4

Closed Dremora closed 7 years ago

Dremora commented 9 years ago

Currently the library can't even be loaded when used on the server. It should not fail and instead fallback to React DOM elements when DOM is not available.

The logic can be demonstrated by the following snippet from my code (but I do believe it should be part of the library):

import React from 'react'
import { canUseDOM } from '../../node_modules/react/lib/ExecutionEnvironment'

let SparkScrollDiv

if (canUseDOM) {
  const sparkScroll = require('react-spark-scroll-rekapi')({
    invalidateAutomatically: true
  })
  SparkScrollDiv = sparkScroll.SparkScroll.div
} else {
  SparkScrollDiv = class {
    render() {
      let { children, ...other } = this.props
      return <div {...other}>{children}</div>
    }
  }
}
export { SparkScrollDiv }
gilbox commented 9 years ago

Thanks for the suggestion. I don't have time to work on this atm, but if you'd like to open a PR for this I'd be happy to merge it.

hsin421 commented 9 years ago

@Dremora thanks! You code snippet works for my isomorphic (or universal) app!

olalonde commented 8 years ago

:+1:

MadeInMoon commented 8 years ago

@Dremora Working for me too on a isomorphic project, but having not this file : _'../../nodemodules/react/lib/ExecutionEnvironment', i had to do like this:

from here:

var canUseDOM = !!(
    typeof window !== 'undefined' &&
    window.document &&
    window.document.createElement
);

It is my first isomorphic app, and It seems to be a reccurent problem. I faced the same problem, and resolved it the same way, with the Halogen loader.

Does any one know how to resolve, in a elegant and global way, this problem?

frinyvonnick commented 7 years ago

I wrote an higher order component to resolve this problem

class ReactSparkLoader extends React.Component {
  constructor(props) {
    super(props)

    this.setRef = this.setRef.bind(this)
    this.state = {}
  }

  setRef() {
    this.setState({
      reactSparkScrollGsap: require('react-spark-scroll-gsap')({
        invalidateAutomatically: true,
      }),
    })
  }

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

    return (
      <div ref={this.setRef}>
        {this.state.reactSparkScrollGsap && children(this.state.reactSparkScrollGsap)}
      </div>
    )
  }
}

Then use it like this :

  <ReactSparkLoader>
    {({ SparkScroll }) => (
      <SparkScroll.div
        timeline={{
          topBottom: { opacity: 0 },
          centerCenter: { opacity: 1 },
        }}
      >
        <p>Some content...</p>
      </SparkScroll.div>
    )}
  </ReactSparkLoader>

@gilbox maybe it could be included to the lib under the name IsomorphicLoader ?

rorz commented 7 years ago

Oh wow, @frinyvonnick — what a god-send!

Your HOC was super easy to implement. It's kind folks like you who make the headache of learning isomorphic apps that little bit less document is not defined-frustrating! 😆

@gilbox — This needs attention ^^^

gilbox commented 7 years ago

@rorz @frinyvonnick I'm happy to add this to the library if you'd like to open a PR

note: it should probably be made generic enough so it works with more than just gsap

frinyvonnick commented 7 years ago

@gilbox I'll open a PR as soon as possible 😄

rorz commented 7 years ago

@frinyvonnick @gilbox — thanks guys!

And, thanks again for a great library, @gilbox

frinyvonnick commented 7 years ago

@rorz @gilbox I made an independant component to load libraries on isomorphic project : https://github.com/frinyvonnick/react-isomorphic-loader

The codebase is currently in a pull-request. A review would be appreciated 😄

Then i'll figure out how to integrate it in react-spark-scroll 🎉

frinyvonnick commented 7 years ago

Hi there, i just published a version 1.0.0 of react-isomoprhic-loader. Do you think it would be great to create wrappers for gasp and others in react-spark-scroll or just mentionning this component in README.md is enough ?

nuclearpidgeon commented 7 years ago

I've been doing my own looking into making this plugin work in server-side rendering, and the main issue I ran into was that the dependant animation-frame package had hard dependencies on window, so whenever the spark-scroll packages are imported/required in nodejs, errors would be thrown.

animation-frame recently released a new v0.3.0 with isomorphic support (see https://github.com/kof/animation-frame/pull/25)

I've been able to successfully use a fork of this package with the updated dependency version for isomorphic rendering (using the static site generator Webpack plugin, which does React rendering in nodejs as part of the Webpack build process). I've submitted a PR for updating the package version: #28

gilbox commented 7 years ago

Thank you @nuclearpidgeon ... published to npm as v3.0.2... if anyone tests this please report back your results here

geloescht commented 7 years ago

This is working for me. Actually, I was worried that it wouldn't work but since it did flawlessly I didn't even check the bug reports here until now.