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

Error rendering component with React.Suspense #522

Closed
allantl opened this issue Feb 2, 2019 · 5 comments
Closed

Error rendering component with React.Suspense #522

allantl opened this issue Feb 2, 2019 · 5 comments

Comments

@allantl
Copy link
Contributor

allantl commented Feb 2, 2019

Got an error with React.Suspense (React 16.7.0). Am I missing something?

import japgolly.scalajs.react._
import japgolly.scalajs.react.vdom.html_<^._
import org.scalajs.dom

object App {

  def main(args: Array[String]): Unit = {

    def body = {
      val main = AsyncCallback
        .pure(<.div(^.color := "#070", "Async load complete."))
        .delayMs(2000)

      React.Suspense(
        fallback = <.div(^.color.red, "Loading..."),
        asyncBody = main
      )
    }

    val Main =
      ScalaComponent
        .builder[Unit]("Main")
        .stateless
        .render_(<.div(^.fontSize := "175%", body))
        .build

    val container = dom.document.getElementById("root")
    Main().renderIntoDOM(container)
  }
}

Browser stack trace:

screen shot 2019-02-03 at 00 55 31

Replication repo: https://github.com/allantl/scalajs-react-suspense

@japgolly
Copy link
Owner

japgolly commented Feb 3, 2019

Hey. I can reproduce your issue locally but there's a twist. If I copy-paste your code into scalajs-react's AjaxExample1.scala and launch gh-pages locally, the same code works fine without any error.

https://github.com/japgolly/scalajs-react/blob/issue/522/gh-pages/src/main/scala/ghpages/examples/AjaxExample1.scala

This suggests to me that it might be an issue with scalajs-bundler or webpack.

@nightkr
Copy link
Contributor

nightkr commented Mar 14, 2019

Looking into the emitted JS (by just running fastOptJS, bypassing the bundler), for some reason it seems to compile this:

val suspenseE = Raw.React.createElement(Raw.Suspense, suspenseP, lazyE)

into this:

var suspenseE = $i_react.createElement($i_react, suspenseP, lazyE);

In other words, for some reason it's passing React as the component, rather than React.Component.

@nightkr
Copy link
Contributor

nightkr commented Mar 14, 2019

This is because japgolly.scalajs.react.raw.Suspense is defined like this:

@JSImport("react", JSImport.Namespace, "React.Suspense")
@js.native
object Suspense extends js.Any

According to the documentation for the relevant overload of JSImport:

Namespace import (import the module itself), with a fallback on a global variable.
When linking with module support, this is equivalent to @jsimport(module, name).
When linking without module support, this is equivalent to @jsglobal(globalFallback).

That means that if compiling for an environment without modules (such as a legacy browser environment) then it's (correctly) interpreted as an alias for React.Suspense, but if compiled for an environment with modules then it gets interpreted as import * as Suspense from "react", which is obviously wrong.

I'll send a PR as soon as I've verified that this fixes the issue.

nightkr pushed a commit to nightkr/scalajs-react that referenced this issue Mar 14, 2019
nightkr pushed a commit to nightkr/scalajs-react that referenced this issue Mar 14, 2019
@japgolly
Copy link
Owner

Hmmm, Github closed this when I merged the PR. v1.4.1 is on its way to Maven Central, give it a try and if this problem persists, please re-open this.

@nightkr
Copy link
Contributor

nightkr commented Mar 17, 2019

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants