Reexporting JSS via index.js causing unwanted rerenders in unrelated components - reactjs

I have a large codebase where Material UI with it's JSS are being used.
jss/
a.js Default or named export `astyle`
b.js Default or named export `bstyle`
index.js - Re-exports the JSS
All other files import like import { astyle } from './jss'
ComponentA.jsx - contains `import { astyle } from './jss'`
ComponentB.jsx - contains `import { bstyle } from './jss'`
App.jsx - imports ComponentA and ComponentB
Updating a.js causes ComponentB to re-render as well, is there any way I can tell webpack to not reload the entire jss/index.js?
Components work fine
componets/
ComponentC.jsx - default or named export
ComponentD.jsx - default or named export
index.js - Re-exports the components
App.jsx - import { ComponentC, ComponentD } from './components'
Updating ComponentC will not re-render ComponentD or components/index.js
I'm looking for the least disruptive solution and would prefer not to import all the styles directly by file name getting rid of the jss/index.js
Here is the demo repo and is based on the example from the fast refresh repo here

Turns out simply upgrading to webpack 5 fixes it, you can view the updated repo at this branch

Related

What happens if two components import the same CSS file in React?

Let's say I have two React components:
import { React } from "react";
import "./styles.css";
function ComponentA() {
...
}
export default ComponentA;
import { React } from "react";
import "./styles.css";
function ComponentB() {
...
}
export default ComponentB;
Both of these components are importing the same CSS file styles.css. Now let's say that in my app, I'm importing both of these components, so App.js looks something like this:
import { ComponentA } from "./ComponentA";
import { ComponentB } from "./ComponentB";
function App() {
return (
<div className="App">
<ComponentA />
<ComponentB />
</div>
);
}
export default App;
What exactly happens here? Does my app import the same CSS file twice? And if so, do I just make the import on the App.js file instead?
It's as if it was only imported once.
When a module bundler like Webpack sees an import, it puts the following path in the list of files to process, if the path doesn't exist already. The file is only processed once, no matter how many times it's imported.
Note that with React apps, you will often see
import React from "react";
in tens or hundreds of files - React isn't created anew hundreds of times. Rather, the module is processed once, and then files that import it are given access to what React has exported.
Importing CSS files works the same way, in that they're only processed once no matter how many times an import exists for them (though they don't really have exports, just side-effects).
If both ComponentA and ComponentB depend on styles.css, feel free to keep importing styles.css in both - it doesn't hurt, and will make things easier to manage when you can see at a glance that both components directly depend on that CSS.

Importing a component from containers (From outside of the scope)

I'm quite new to react and am having some troubles with this basic problem.
From HomeLander.js - How can I import a Button, and a P? They are, as expected, not in the same scope. Is there a neat way to do this?
My directories are structured in this way:
Components/
Button/
index.js
P/
index.js
Containers/
HomeLander/
index.js
Index.js ("Main" JS file)
you can try this
import Button from '../../Components/Button'; (given Button component is default export)
import { Button } from '../../Components/Button'; (if Button component is not default export)
Same way with 'P'

Importing React Components and Images with require()

In React, what are the differences between loading an image vs. loading a component using require()?
When I load an image using require("image path"), it works. When I load a React component using require("component") I get an error.
For images in React, You need to require
<img src={require('../assests/logo.png')} />
But it is totally different case with components. You import React components bases on how you exported.
And use ES6 to import and export in reactjs
And there are two types of exports
Named Export
Named exports are useful to export several values at ones. During the import, it is important to use the same name.
// how to export
export function myfunc() {}
// how to import
import { myfunc } from './myfile';
Default export.
Default exports are useful to export only a single value. During the import, able to omit the curly bares and use any name.
// how to export
default export function() {}
// how to import
import anynameyouwant from './myfile';

React won't import my module "Module not found: Can't resolve "

React is not resolving my component import into my YouTubeApp.js.
It seems silly, i have other components in my react app that I'm able to import with no issues but this one in particular i can't get it imported.
Github: https://github.com/JAlonsoHdz/React_UnsplashClientApp/tree/master/src/components
Additional context, YouTubeApp.js is currently imported in my index.js with no issues. I'm using react routing imported in the index.js and links and the route links sucessfully to YouTubeApp.js. The problem arise whenver I try to import ANY component into YouTubeApp.js i get the Cannot resolve 'component name' error, without any imports the component YouTubeApp.js works fine.
I have validated the correct path, the name of the component.
YouTubeApp.js
import React from 'react';
import Other from './components/other';
class YouTubeApp extends React.Component {
render() {
return (<p>test</p>
);
}
}
export default YouTubeApp;
And this is my component I'm trying to import:
import React from 'react';
class Other extends React.Component {
render() {
return (
<div clasNames="ui container">test!</div>
);
}
}
export default Other;
I need to nest at least a few levels down more components but this issue blocking.
Looking at your GitHub repository, it appears that YouTubeApp.js and other.js are both in the "components" directory. Therefore when in YouTubeApp.js (or any other component in your "components" directory) your import should be:
import Other from './other';

No stylesheet generated by styled-components on nwb reusable component

I've built a reusable react component through nwb new react-component fade-preloader called FadePreloader which uses styled-components, its published on npm so I can use it on other projects, but when its imported as a module its styles are never added to the DOM. The following provides more details about the nwb component.
src folder is:
src/
FadePreloader.js
FadePreloader.Styled.js
index.js
FadePreloader.js:
import React, {Component} from "react"
class FadePreloader extends Component {
// logic code
}
export default FadePreloader
FadePreloader.Styled.js:
import styled from "styled-components"
import FadePreloader from "./FadePreloader"
const FadePreloader_Styled = styled(FadePreloader)`
// css here
`
export default FadePreloader_Styled
index.js:
// just import the styled-componet and re-export it
import FadePreloader from "./FadePreloader.Styled"
export default FadePreloader
I have the default configuration in package.json provided by nwb:
FadePreloader is published on npm so I added it on other project (through yarn add fade-preloader) and use it like this:
App.jsx on other project:
// lots of imports here
import FadePreloader from "fade-preloader"
class App extends Component {
render() {
return(
<div>
<FadePreloader />
</div>
)
}
}
export default App
The FadePreloader component is rendered in the DOM and its class attribute has the className generated by styled-components as espected but the stylesheet is never added to the DOM, no <style> element is present causing an unstyled FadePreloader rendered. What's wrong?
I've found a solution coming from the official spectrum channel of styled-components, see here.
What I had to do was to follow this which basically says that styled-components dependency needs to be moved from dependencies to devDependencies and peerDependencies in package.json. I'm not sure the reason but it seems to be to avoid some unexpected reason that is generated by duplicated direct dependency of styled-components.

Resources