Skip to content
This repository has been archived by the owner on Dec 16, 2021. It is now read-only.

Children is array. #242

Closed
BANG88 opened this issue Nov 23, 2016 · 18 comments
Closed

Children is array. #242

BANG88 opened this issue Nov 23, 2016 · 18 comments
Labels

Comments

@BANG88
Copy link

BANG88 commented Nov 23, 2016

Same code works well with React but not work with Preact-compat.

When use Preact with react-redux it seems like:

image

When use React:

image

ENV:

    "preact": "7.0.3", // same as 6.4.0
    "preact-compat": "^3.9.2",
@developit developit added the bug label Dec 2, 2016
@developit
Copy link
Member

Hi @BANG88 - sorry for letting this issue slip through the cracks! Children should be normalized to look like React's, but it seems like there's a combination of components that circumvents that normalization. I'll look into it!

@aweary
Copy link
Contributor

aweary commented Dec 9, 2016

@developit any idea what combination of components might be causing this? I've having the same issue (with the same component, Provider) and I'd be happy to look into this if you have a recommended starting point.

@developit
Copy link
Member

Hey - best possible thing would be a stack trace from the point where children was seen as an array.

@aweary
Copy link
Contributor

aweary commented Dec 9, 2016

@developit thanks, doing that now. Here's the stack trace if you want to check it out:

Invariant Violation: React.Children.only expected to receive a single React element child.
    at invariant (/Users/brandondail/projects/walmart/oss/electrode-redux-router-engine/node_modules/fbjs/lib/invariant.js:38:15)
    at Object.onlyChild [as only] (/Users/brandondail/projects/walmart/oss/electrode-redux-router-engine/node_modules/react/lib/onlyChild.js:33:84)
    at Provider.render (/Users/brandondail/projects/walmart/oss/electrode-redux-router-engine/node_modules/react-redux/lib/components/Provider.js:51:28)
    at renderToString (/Users/brandondail/projects/walmart/oss/electrode-redux-router-engine/node_modules/preact-render-to-string/src/index.js:90:18)
    at ReduxRouterEngine._renderToString (/Users/brandondail/projects/walmart/oss/electrode-redux-router-engine/lib/redux-router-engine.js:109:16)
    at /Users/brandondail/projects/walmart/oss/electrode-redux-router-engine/lib/redux-router-engine.js:97:22
    at bound (domain.js:280:14)
    at runBound (domain.js:293:12)
    at tryCatcher (/Users/brandondail/projects/walmart/oss/electrode/samples/universal-react-node/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (/Users/brandondail/projects/walmart/oss/electrode/samples/universal-react-node/node_modules/bluebird/js/release/promise.js:510:31)
    at Promise._settlePromise (/Users/brandondail/projects/walmart/oss/electrode/samples/universal-react-node/node_modules/bluebird/js/release/promise.js:567:18)
    at Promise._settlePromise0 (/Users/brandondail/projects/walmart/oss/electrode/samples/universal-react-node/node_modules/bluebird/js/release/promise.js:612:10)
    at Promise._settlePromises (/Users/brandondail/projects/walmart/oss/electrode/samples/universal-react-node/node_modules/bluebird/js/release/promise.js:691:18)
    at Async._drainQueue (/Users/brandondail/projects/walmart/oss/electrode/samples/universal-react-node/node_modules/bluebird/js/release/async.js:138:16)
    at Async._drainQueues (/Users/brandondail/projects/walmart/oss/electrode/samples/universal-react-node/node_modules/bluebird/js/release/async.js:148:10)
    at Immediate.Async.drainQueues (/Users/brandondail/projects/walmart/oss/electrode/samples/universal-react-node/node_modules/bluebird/js/release/async.js:17:14)
    at runCallback (timers.js:637:20)
    at tryOnImmediate (timers.js:610:5)
    at processImmediate [as _immediateCallback] (timers.js:582:5) name: 'Invariant Violation', framesToPop: 1

@developit
Copy link
Member

hmm - interesting that it's happening when rendering to string. Will see if that could be related!

@developit
Copy link
Member

developit commented Dec 9, 2016

Little confused how react is making its way into the bundle though - it seems like react-redux is actually ending up with a copy of React itself, not preact-compat. That will definitely mess some things up haha

How are you aliasing preact-compat in for react?

@aweary
Copy link
Contributor

aweary commented Dec 10, 2016

How are you aliasing preact-compat in for react?

That's probably the issue, I'm using webpack aliases for the client bundle, but we don't bundle our server code. Instead we're using babel-register to run it directly.

I'm trying to get the server's babel config setup to alias react and react-dom using:

       ["module-resolver", {
       "alias": {
           "react": "preact-compat",
           "react-dom": "preact-compat"
       }
       }]

But it doesn't seem to change that react-redux is getting a copy of react instead of preact-compat.

@aweary
Copy link
Contributor

aweary commented Dec 10, 2016

It might be related to our ignore pattern we use with babel-register https://github.com/electrode-io/electrode/blob/master/samples/universal-react-node/server/index.js#L22-L24

@developit
Copy link
Member

Ahh yes. I was trying to recall if there was a good require alias module for node. I know I've used a few, but it's difficult thing to search for.

@aweary
Copy link
Contributor

aweary commented Dec 12, 2016

I went ahead and just monkey-patched it myself, and it does work now! Not a great long term solution, but it's better than nothing I suppose 😄

var Module = require("module");
const originalRequire = Module.prototype.require;
Module.prototype.require = function() {
  if (arguments[0] === "react" || arguments[0] === "react-dom") {
    arguments[0] === "preact-compat";
  }
  if (arguments[0] === "react-dom/server") {
   arguments[0] = "preact-compat/server";
  }
  return originalRequire.apply(this, arguments);
}

So I think it's safe to say this error is likely due to react or react-dom not getting aliased properly.

edit: it does look like something is going wrong with server rendering though, as I'm getting back "[object Object]" now 😕

@developit
Copy link
Member

Hmm - what are you calling for your server render?

@aweary
Copy link
Contributor

aweary commented Dec 12, 2016

@developit sorry for the noise, it looks like we were using some internal React modules in electrode-react-ssr-caching and that was causing the issue.

@ryan-codingintrigue
Copy link

I am seeing the same issue using babel-register to alias the modules.

Monkey-patching require using module-alias seems to fix the issue. Does the issue lie with preact-compat or with react-redux?

@developit
Copy link
Member

@ryan-codingintrigue The issue is that Babel (as applied via babel-register) only runs on your code, not code from node_modules. That means your aliases are not being applied to react-redux. The module-alias fix works because it applies your aliases across the entire runtime, not just code transpiled via Babel. There is no issue with any given library, just whichever aliasing solution you choose needs to be applied to the entire codebase, not just your first-party code.

@ryan-codingintrigue
Copy link

Makes sense thanks! Will leave the require hook in place then, as I'm using Webpack on the front end anyways.

@developit
Copy link
Member

Yup! FWIW, if you were you bundle with Webpack (or reuse your frontend bundle as a UMD bundle), those aliases would work in Node. A lot of people use that technique via static-site-generator-webpack-plugin.

@developit
Copy link
Member

Should we close this issue? It seems like the underlying cause is usually a broken alias.

@developit
Copy link
Member

Closing since the cause is a broken alias. Please re-open if it's still an issue!

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

No branches or pull requests

4 participants