-
-
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
Major change to fix issues with React Hooks #1268
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 21 of 21 files at r1.
Reviewable status: all files reviewed, 3 unresolved discussions (waiting on @justin808)
CHANGELOG.md, line 28 at r1 (raw file):
### [12.0.0] #### BREAKING CHANGE In order to solve the issues regarding React Hooks compatability:
compatibility
node_package/src/createReactElement.ts, line 41 at r1 (raw file):
// TODO: replace any let ReactComponent: any;
According to our current types, the return of a RenderFunction
should always be a ReactElement
.
Seems like we need two types: one for the 2 param generatorFunction & another for the 0-1 param renderFunction, which is what the generatorFunction would return?
spec/dummy/client/app/startup/ClientRenderedHtml.jsx, line 20 at r1 (raw file):
// You may do either: // export default (props, _railsContext) => () => <EchoProps {...props} />;
I'm confused. This is the same as the line above it, which won't work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: all files reviewed, 3 unresolved discussions (waiting on @Judahmeek and @justin808)
spec/dummy/client/app/startup/ClientRenderedHtml.jsx, line 20 at r1 (raw file):
Previously, Judahmeek (Judah Meek) wrote…
I'm confused. This is the same as the line above it, which won't work?
One vs two props
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: all files reviewed, 3 unresolved discussions (waiting on @Judahmeek and @justin808)
node_package/src/createReactElement.ts, line 41 at r1 (raw file):
Previously, Judahmeek (Judah Meek) wrote…
According to our current types, the return of a
RenderFunction
should always be aReactElement
.Seems like we need two types: one for the 2 param generatorFunction & another for the 0-1 param renderFunction, which is what the generatorFunction would return?
Yes
After this commit, going to change the logic to reverse the check for reactComponent vs. Generator function
@@ -34,7 +34,7 @@ const DeferredRenderAppServer = (_props, railsContext) => { | |||
return { error, redirectLocation }; | |||
} | |||
|
|||
return <RouterContext {...routerProps} />; | |||
return () => <RouterContext {...routerProps} />; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes sense, @Judahmeek. It needs a React function component, not JSX.
end | ||
context "render function that takes props" do | ||
include_examples "React Component", "div#HelloWorldApp-react-component-7" | ||
include_examples "React Component", "div#HelloWorld-react-component-7" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An idea on why this changed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those are the Ids that you used in your initial commit: be37b34?file-filters%5B%5D=.erb#diff-13675373e6eaa2b6e91995c3ec8974f7
Only pending thing for merge is to double check the CHANGELOG, README, and upgrade docs. |
@@ -5,6 +5,54 @@ If you would like help in migrating between React on Rails versions or help with | |||
|
|||
We specialize in helping companies to quickly and efficiently move from versions before 9 to current. The older versions use the Rails asset pipeline to package client assets. The current and recommended way is to use Webpack 4 for asset preparation. You may also need help migrating from the `rails/webpacker`'s Webpack configuration to a better setup ready for Server Side Rendering. | |||
|
|||
## Upgrading to v13 | |||
* Make sure that are are on a relatively more recent version of rails and webpacker. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is extra are
. Please remove.
|
||
If you used yarn link, then you'll have two versions of React installed. | ||
|
||
Instead use Yalc. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cool.
CONTRIBUTING.md
Outdated
yarn run build | ||
yarn install-react-on-rails | ||
yarn run build:watch | ||
yalc pubish react-on-rails |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
publish
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @tahsin352 for your review!!!!
@Judahmeek did we get all of these?
Thanks for the help @Judahmeek! |
Glad to see this merged! Should we expect React on Rails v12 to be released soon? |
@justin808 this is great, appreciate your work! |
OMG! Your thank you messages really fire me up! I'll try to get this one by this weekend! BTW, if any of you can consider even the tiniest sponsorship, that would be so appreciated! |
See details in #1198
BREAKING CHANGE
I’m updating React on Rails. The new API for ReactOnRails.register will take an object which registers either
The update concerns render-functions (formerly called "generator functions"). Previously, generator functions would return JSX and there were sort of like a React function component. But not quite, as you could not use React Hooks within them.
With this update, render-functions need to return either a
Note, you can no longer return JSX!
If you use React component or create a function that returns a React component, then the React on Rails library will call React.createElement and then call ReactDOM.render (or hydrate).
This ensures that React Hooks can always be used with both the React functional or class components and render-functions.
In the case of the render-function, if you could just return the React element (or JSX) and you used the hook API, then you’d get an obscure “hooks don’t work” error.
Use regular React functional or class component or a render-function for your client-side bundle:
Or a render-function. Note you can't return just the JSX (React element), but you need to return either a React functional or class component.
Note, this doesn't work, because this function just returns a React Element
While this does result in changing all the cases that looked like a React functional component, but had 2 params, I do believe this is worth it.
#1268 Performance?
In my update to React on Rails, I’m changing some APIs. I’m wondering if calling a function to create a function that has a closure with say very a large props JS object, and then returning that function and then
the function will again be called by React.createElement(MyComponent, props)…So the props passed to the React function are not really necessary b/c they can be in a closure.
I’m concerned that having the props passed to the real React component will be bad for performance if they already should be used from the closure. However, JavaScript passes objects by reference, so I don't see any issue.
This could be optimized by not passing any props (which would go into unused param _props below). However, that’s going to be confusing in some cases. I can see people defining the inner component using the same name props and that would shadow the outer one.
This change is