-
-
Notifications
You must be signed in to change notification settings - Fork 631
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
React Hooks (Hooks can only be called inside the body of a function component) #1198
Comments
Got same problem there, i tried a couple of react suggestion(veryfing i'm using hooks correctly, and veryfing that i got a single version of React) but it's not one of them... |
@lukaskamp @amauryfischer can one of you give me a simple reproduction case? a github repo? |
As a note, a quick fix for this is to just wrap your React On Rails rendered component in a function, like this:
|
@wuz didn't work, same error :
|
@amauryfischer Is that the exact code you are using? That Using |
Yes my bad @wuz , but even corrected
got the same error.
in the return. |
We're having the same issue. We have multiple components rendering on the same page. We believe this is related to the issue described in the react docs about loading 2 instances of React, possibly. The easiest way to reproduce is to make 2 components with hooks and register them then pass those two into a Rails view. If I have enough time later today I'll make a reproduction repo and update this comment. |
@juliusdelta Exactly ! I love you so much. Finally find out why my hooks wasn't working thanks to you. I'm happy, was searching for this since a whole month |
I've put together a minimal reproduction repo that can be found here. As suggested by @wuz above, the error is thrown based on the way we export the component: // Works ✅
export default props => <HelloWorld {...props} />;
// Fails 🔴
export default HelloWorld; Here's the error message: I've tried using the latest I've been recently dealing with this problem in our app (not using |
@janklimo's workaround above using Unfortunately, when the page contains multiple So as it stands right now, it appears to just not be possible to use react hooks while rendering multiple components on the same page. This is a pretty serious problem, and seems to mean the only way to work around this is to rewrite components without using hooks at all (at any level of the component tree, when using multiple components o the same page). |
After some further investigation on this, and reading this issue carefully, I realized my particular issue was the inclusion of multiple bundles on the same page. The problem with two or more I was able to work around this problem by consolidating multiple packs into one to ensure that only one React copy was loaded. After that, @janklimo's fix using |
@rubiety Having multiple copies of React sent to the browser is also bad for performance. So definitely having on copy of React is correct. I'm puzzled by why react-rails would not have issues. I looked at the source code there and I could not find anything notable. @janklimo I really appreciate your help on this issue. If anybody trying to debug this wants to pair with me, please schedule a time with my calendar link or email me for a Slack invite. |
@justin808 I have further checked the problem. several others also faced this issue with react hooks. ref. facebook/react#13991 To solve 'multiple instances of react' error, I have tried some other ways like below:
again, I have also tried with npm link package. but it also didn't solve the error. Can i symlinked dependencies use their own copy of react in a react_on_rails gem file ??? |
I had the same problem which occurred when I tried to render a second component. Few hours of debugging later I realised that the problem was not related to having two components actually, but the fact that a root component (the one that I put in my view) was the one using As soon as I wrapped it in another component that didn't use the hook all was fine with the world again. In other words, hooks for some reason can't be in root component that you are rendering with |
@filipkis nice finding, thanks |
I migrated from webpacker 3.6.0 to 4.0.7 and started seeing this error. Maybe this can help track down the issue? I have only one component in my view, wrapping does work. |
Any news about this ? Because I can't use hooks anywhere.. |
We have been noticing this issue as well, it seems to occur possibly when we use
|
Was going to add, if you come up on this problem just try this:
As of yet I have no idea why that works. Not sure if this project is being actively maintained anymore. |
I think the issue is that React on Rails will call a function component like a normal function here, but the hooks code doesn’t expect for components to be used like that; I think it only expects function components to be passed to In light of this @justin808, what do you think about removing this snippet? if (generatorFunction) {
return component(props, railsContext);
} |
@jacksonrayhamilton React on Rails allows you to create a function that takes 2 params, the props and the railsContext, and then your function should return a React component. So I'm not totally clear on what you're suggesting. Can you create a simple example to demonstrate this? |
Sure. In my pack file I have a function component that uses a hook, and I register this component: import React, { useState } from 'react'
function HelloWorld() {
const [whom] = useState('Everyone')
return <div>Hello {whom}!</div>
}
ReactOnRails.register({ HelloWorld }) In my Rails template I render it: <%= react_component('HelloWorld', prerender: false) %> When I load up the page, I see that when my function component is being registered, Thus when I advance to the error, we can see that React is unhappy about Because a function component was called outside the React rendering process… And thus So I think the key is that “ |
This is nuts ... if anyone wants a working example of HMR with react-rails that supports hooks, look at this: https://github.com/Leap-Forward/react-rails-hmr . |
Well, I don’t think react_on_rails users need to resort to a whole new gem to fix their problem. I think in my last comment here I narrowed in on the problem and I expect it will be pretty easy to solve in the react_on_rails source. Maybe with a breaking API change at worst? I expect @justin808 has just been busy. Hooks are relatively new. I respect his choices in prioritizing his time. |
Awesome to hear from you all. We're working on some updates to the sample apps. @jacksonrayhamilton I think you hit the nail on the head! The core issue is that we would like a way that we can infer if a function is for a React Component or just a function. So the source links:
Either we have to fix the How about if we use [Function.length](the https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/length)? If the length is 2, then we assume a generator function that will take two args:
If the length is 3, we already assume that this is a "renderer" which is used for lazy loading. If the length is zero or 1, then we can assume that this is simple React Component. Thus, we can then call the React.createElement API I took a try at this fix: @behraaangm @Judahmeek @ashgaliyev can you guys please comment? @jacksonrayhamilton thank you for your contribution!. Do you want a one-month free subscription to React on Rails Pro? I'm going to formalize this more soon on the main https://www.shakacode.com website. |
I merged #1280. It console.errors with a detailed message. I'll just throw for the following major version. I want to ship v12 soon! |
@jacksonrayhamilton @sharjeel288 @dchersey @filipkis @lukaskamp @amauryfischer @wuz @juliusdelta @janklimo @rubiety @tahsin352 @batamire @theocerutti @aflansburg Any of you want to help me test the master branch? I think we're close. I could also create a beta version on rubygems and npm if one of you wanted that. |
@jacksonrayhamilton @sharjeel288 @dchersey @filipkis @lukaskamp @amauryfischer @wuz @juliusdelta @janklimo @rubiety @tahsin352 @batamire @theocerutti @aflansburg Gem version: 12.0.0.pre.beta.0 and npm version 12.0.0-beta.0 released! Please try this out! https://www.npmjs.com/package/react-on-rails |
Fixed in v12! |
@jacksonrayhamilton @sharjeel288 @dchersey @filipkis @lukaskamp @amauryfischer @wuz @juliusdelta @janklimo @rubiety @tahsin352 @batamire @theocerutti @aflansburg Hey, hey, React on Rails v12 has shipped! |
Awesome, thanks @justin808! |
I'm running a new Rails app with ruby 2.7.1 and Rails 6.0.3.4. I followed this tutorial and got the same error message as well.
Gemfile:
|
@imgarylai Can you please share your repo on Github. If you're 100% sure this is an issue, please open a new issue. |
Might be related to React v17. The tutorial steps will get the latest React. https://github.com/facebook/react/blob/master/CHANGELOG.md#1700-october-20-2020 |
@imgarylai can you try to adjust the steps so that you don't use React 17 to isolate if that is the cause? |
@justin808 Thank you! I will try it again and use |
@justin808 I received the same error with the demo when installing on a new app |
@jwcatprint are you using React 17? I'll look into this no later than this coming weekend. In the meantime can somebody confirm that
solves the issue. |
PRs welcome! |
Moving over to a new issue #1336. |
This should have been fixed in 12.0.4. |
In case anyone else is stuck on the same issue I am (unrelated to other fixes so far): I've been getting this on 12.2... turned out to be because of this issue which is caused by adding multiple calls to For now, the fix is to only call |
I'm reopening this issue just to make it clear that javascript_pack_tag needs to be only once on the view, including the layout when using rails/webpacker v6. |
Referencing shakacode/shakapacker#39 because solving that would help here. |
Fixed a long time ago. |
I'm trying Testing React Hooks with react_on_rails gem and noticed there is a Error:
"Hooks can only be called inside the body of a function component error."
Without using ReactOnRails config (e.g in packs/applications.js) everything works correctly. Also when I used react-rails gem everything works.
Where could be problem ?
The text was updated successfully, but these errors were encountered: