Has anybody gotten React components in Atmosphere packages working in v3?
I’m getting the following error:
In the past, there have been some problems with functional React components getting compiled down to object oriented React components, which then breaks the Rules of Hooks downstream. Has that been migrated/rewritten yet? Are packages warranted to work in v3? Or is that a 3.1 feature?
Update: My package.js
file looks like this:
Package.onUse(function(api) {
api.versionsFrom('3.0');
api.use('meteor@2.0.0');
api.use('webapp@2.0.0');
api.use('ecmascript@0.16.9');
api.use('react-meteor-data@3.0.0');
api.use('session');
api.use('mongo');
api.use('http');
api.mainModule('index.jsx', 'client');
});
Npm.depends({
"react": "18.3.1",
"@mui/material": "5.16.7",
"@emotion/react": "11.13.0",
"@emotion/styled": "11.13.0",
"@mui/icons-material": "5.15.13"
})
Do you happen to have a minimal reproduction I could check out?
1 Like
A nitpick, I think that the NPM dependencies for the most part can be left to the app itself, like react
package. That should make it a bit easier and prevent some dependency issues.
As for not being able to export, everything else looks fine, so next we would have to look on index.jsx
. Minimal reproduction would be great.
1 Like
@awatson1978 additionally to what @storyteller wrote, I would also add to avoid pinning any explicit versions on core packages, like in your example
api.use('meteor@2.0.0');
api.use('webapp@2.0.0');
api.use('ecmascript@0.16.9');
api.use('react-meteor-data@3.0.0');
because they are resolved by api.versionsFrom('3.0');
for best compatibility. The result with best compat. would look like this:
Package.onUse(function(api) {
api.versionsFrom('3.0');
api.use([
'ecmascript',
'meteor', // not sure if even necessary to add this one
'webapp',
'react-meteor-data',
'session',
'mongo',
'http',
])
api.mainModule('index.jsx', 'client');
});
2 Likes
@copleykj
Yeah, for sure. I’d appreciate any help or extra eyes on this. Minimal reproduction below.
The architecture pattern with dynamic routes works in all of my packages in Meteor 2.x
However, there has been a long standing problem in v2.x, where React functional components in Atmosphere packages would semi-break, because the Atmosphere compile chain would compile them down onto a React object component, which then would break the Rule of Hooks and loose props propagation.
I’m personally convinced this has to do with the Atmosphere package compile pipeline being a separate thing than the main compile pipeline.
I am not sure whether you ask specifically for an Atmosphere package or a local Meteor package would do it.
I use React functional components with hooks inside local Meteor packages. An “optimization” I did was to refrain from referencing React at the Meteor package level. I have React globalized in the app and I do not import it anywhere anymore, I only import the hooks.
In order to globalize React you can add these to lines in a file and import it at the top of the client startup.
import React from 'react'
window.React = React
Everything works ok but I don’t use React Context. Instead I use Redux and looking at it, I have an idea.
Your Context is declared in your main project I guess. How about you declare all actions and states in the main project and pass them as props to your parent React component in the Meteor package.
BTW, I use MUI too. MUI in Meteor is not tree-shakeable at compilation but there are other methods to do it … less convenient though.
1 Like
Oooh, I’m liking this idea. This could be workable. Avoid the Rule of Hook errors.
Maybe I need to read up on React Context again. I worked on it one time, like 5 years ago, and never touched it again. Maybe I need to do the same for this migration.
And to your question… Meteor packages were introduced around the same time as Atmosphere, and there was a time when they were called “Atmosphere packages” back in, I guess 0.6.5 days? 0.7? So, yes, a local Meteor package suffices; no need to deploy to Atmosphere; I just call them Atmosphere packages because old habits die hard.
Happy to report that, with your all’s nudging, I think I managed to get it working.
There were two things involved. First, I needed to add in the ThemeContext, like so:
const ThemeContext = createContext();
export const useTheme = () => useContext(ThemeContext);
export const ThemeProvider = ({ children }) => {
const [theme, setTheme] = useState('light'); // Example state for the theme
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
{children}
</ThemeContext.Provider>
);
};
And then later in the App:
export const App = () => (
<div>
<React.StrictMode>
<ThemeProvider>
<RouterProvider router={router} />
</ThemeProvider>
</React.StrictMode>
</div>
);
After that, I also needed to remove duplicate libraries, and I wound up deleting the entire Npm.depends() section. So, this is an improvement over v2.x, that we don’t have to specify this! This is good!
// Npm.depends({
// "react": "18.3.1",
// "@mui/material": "5.16.7",
// "@emotion/react": "11.13.0",
// "@emotion/styled": "11.13.0",
// "@mui/icons-material": "5.15.13"
// });
1 Like
I’m probably going to have to rebuild from this new template. But I think I’m on the home stretch to being able to migrate all of our workflow packages, and run them in v3 without having to completely rewrite them. That’s great news!
Thank you for the help and suggesting that I build a minimum reproduction!
2 Likes
Glad to hear your getting things working. One thing that might also help here, is that since your not really doing anything meteor specific it might be easiest to make this a node package. It’s not all that hard to setup and might avoid some weird edge cases of the isobuild system.
1 Like