How does webpack handle multiple files importing the same module React - reactjs

I have a React app which has many components importing the same modules. Does webpack import each module once for each file requesting it, resulting in duplicate code(in this case each import twice for just the two components)? I'm considering re-writing the components so that child components do not need to require the React modules, but maybe I'm solving a problem that doesn't exist. I'd like to avoid many imports of the same react module if it results in duplicate code.
Component 1
import React from "react";
import { Link } from "react-router";
import ReactLogo from "elements/ReactLogo";
export default class MainMenu extends React.Component {
render() {
return <div>
<ReactLogo type="svg" /> <ReactLogo type="png" /> <ReactLogo type="jpg" />
<h2>MainMenu:</h2>
<ul>
<li>The <Link to="home">home</Link> page.</li>
<li>Do something on the <Link to="todo">todo page</Link>.</li>
<li>Switch to <Link to="some-page">some page</Link>.</li>
<li>Open the chat demo: <Link to="chat" params={{room: "home"}}>Chat</Link>.</li>
<li>Open the page that shows <Link to="readme">README.md</Link>.</li>
</ul>
</div>;
}
}
Component 2 importing the same 3 modules.
import React from "react";
import { Link } from "react-router";
import ReactLogo from "elements/ReactLogo";
export default class MainMenu extends React.Component {
render() {
return <div>
<ReactLogo type="svg" /> <ReactLogo type="png" /> <ReactLogo type="jpg" />
<h2>MainMenu:</h2>
<ul>
<li>The <Link to="home">home</Link> page.</li>
<li>Do something on the <Link to="todo">todo page</Link>.</li>
<li>Switch to <Link to="some-page">some page</Link>.</li>
<li>Open the chat demo: <Link to="chat" params={{room: "home"}}>Chat</Link>.</li>
<li>Open the page that shows <Link to="readme">README.md</Link>.</li>
</ul>
</div>;
}
}

No, webpack (similar to browserify and other module bundlers) will only bundle it once.
Every react component will get its own scope, and when it requires/imports another module, webpack will check if the required file was already included or not in the bundle.
So no, it will not result in duplicate code. However if you import some external packaged libraries, you may have some duplicate code. In that case, you can use Webpack's Deduplication plugin to find these files and deduplicate them. More info here for that: https://github.com/webpack/docs/wiki/optimization#deduplication

Related

How do I embed Jobber request form in a react app

I am trying to embed a jobber request form in my react application but I am not sure how to go about this https://stackoverflow.com/questions/73739326/how-to-render-embedded-html-with-multiple-tags-in-react/73743146#73743146 has a similar question where the use of react-helmet was the solve.
I'd like for it to be button that would activate the form request. I have the button built, but not sure how to integrate the code below to make it all work.
import React from "react";
import { Helmet } from "react-helmet";
export default class Jobber extends React.Component {
render() {
return (
<div className="Application" id="f6f2802e-49e8-477b-b405-8b2b18dded97">
<Helmet>
<div id="f6f2802e-49e8-477b-b405-8b2b18dded97"></div>
<link
rel="stylesheet"
media="screen"
href="https://d3ey4dbjkt2f6s.cloudfront.net/assets/external/work_request_embed.css"
/>
<script
src="https://d3ey4dbjkt2f6s.cloudfront.net/assets/static_link/work_request_embed_snippet.js" clienthub_id="f6f2802e-49e8-477b-b405-8b2b18dded97" form_url="https://clienthub.getjobber.com/client_hubs/f6f2802e-49e8-477b-b405-8b2b18dded97/public/work_request/embedded_work_request_form"
/>
</Helmet>
</div>
);
}
}
'''
I just have a blank page.

How to create React.js app without a function in App.js

I just finish typing npx create react app to create a react app but for some reason my App.js is a function not a class
eg)
result:
function App() {
return ()
I want something like:
Class app extends components{
render (return())
}
I could write it down manually but i want the class app as default when i create an app so could anyone tell me what is the cause of this?
That just comes out of the box now for React. You can make your App.js a stateless functional component OR a class component.
class App extends React.Component{
render(){
return(
<div>Hello World</div>
)
}
}
With the introduction of hooks in React 16.8 functional components can be stateful and supposed to replace class components in most cases. This is the reason why App is functional component in a project that is generated with create-react-app, more specifically react-scripts package.
It's possible to initialize the project with older react-scripts as a template:
create-react-app foo --scripts-version react-scripts#^2
And then update it to latest version:
npm -S react-scripts#^3
Since create-react-app provides static boilerplate for a project, and doesn't have scaffolding features, it's possible to copy and paste App from previous react-scripts version:
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class App extends Component {
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
}
export default App;
As mentioned by #FaizanMubasher, the class Components were not very reusable, and they were lacking a sense of interchangeability. It makes no sense to copy class component code from previous versions.
It will be ideal to use move away from class components and start using function components.
here is an example for anyone seeking the right approach.
import React from 'react';
import Layout from './components/Layout/Layout';
function App() {
return (
<div className="App">
<Layout />
</div>
);
}
export default App;
function component Layout:
import React from 'react';
import Aux from '../../hoc/Aux';
const layout = (props) => (
<Aux>
<div>TOOLBAR, SIDEDRAWER, BACKDROP</div>
<main>
{props.children}
</main>
</Aux>
);
export default layout;

How to add js to React components in Gatsby?

I'm trying to add the scroll function in script tags to this header component in Gatsby. I know it could work in html and not in react, but what is the right way to do it? Thanks!
import React from 'react'
import Link from 'gatsby-link'
import './header.css'
const Header = () => (
<div className='Header'>
<div className='HeaderGroup'>
<Link to='/'><img src={require('../img/logo_nav.png')} width='60' /></Link>
<Link to='/index'>Selected Works</Link>
<Link to='/uber'>Uber Thoughts</Link>
<Link to='/awards'>Awards</Link>
<Link to='/about'>About</Link>
</div>
</div>
)
export default Header
<script>
$(window).scroll(function () {
if ($(window).scrollTop() > 10) {
$('.Header').addClass('floatingHeader');
} else {
$('.Header').removeClass('floatingHeader');
}
}
</script>
If you want scripts to load before the DOM is ready you can add your scripts inside html.js file.
From the Gatsby docs:
Gatsby uses a React component to server render the and other
parts of the HTML outside of the core Gatsby application.
Read more about it here.
In your case, what you can do is to write your script inside the componentDidMount react lifecycle method, because you need access to the DOM (as you're using jQuery there) you need to run the script after the body has been loaded, so placing your script in the <head> won't work, you need to add it inside the componentDidMount method by first making your component a class component to get access to the react lifecycle methods.
import React from 'react'
import Link from 'gatsby-link'
import $ from 'jquery'
import './header.css'
class Header extends React.Component {
componentDidMount () {
$(window).scroll(function () {
if ($(window).scrollTop() > 10) {
$('.Header').addClass('floatingHeader');
} else {
$('.Header').removeClass('floatingHeader');
}
})
}
render () {
return (
<div className='Header'>
<div className='HeaderGroup'>
<Link to='/'><img src={require('../img/logo_nav.png')} width='60' /></Link>
<Link to='/index'>Selected Works</Link>
<Link to='/uber'>Uber Thoughts</Link>
<Link to='/awards'>Awards</Link>
<Link to='/about'>About</Link>
</div>
</div>
)
}
}
export default Header
You can also use a Gatsby layout template like the gatsby-starter-blog project and put your script at the bottom of the {children} call as a <script>Your script</script> and it will be available in all your pages, same as using the html.js file but since you need access to the DOM you need to put it inside the body for your script to work (more info about Gatsby layouts here).

Using next js for a static website

error - React.Children.only expected to receive a single React element child.
There were quite a few questions with the same context, I tried those solutions but have not found a solution.
The Navbar of the website is what is giving me the error. There is a section over the Navbar which renders properly, when I try to render the Navbar below it throws the error.
import Link from 'next/link'
import Head from '../components/head'
import Download from '../components/nav'
import NavBar from '../components/header'
import Footer from '../components/footer'
import htmlContent from 'html-loader!../legacy/index.html'
const Homepage = () => (
<div>
<Head />
<Download/>
<NavBar />
<div dangerouslySetInnerHTML={{__html: htmlContent}} />
<Footer />
</div>
);
export default Homepage
The footer shows properly, head tag is for all the meta data etc(also works). Github link to all the code is-https://github.com/yohanelly/website-jsx/tree/master/components
The problem is with the whitespace between the Link and the a tag.
<Link href="#"> <a className="menu-links features">Features</a></Link>
should be either
<Link href="#"><a className="menu-links features">Features</a></Link>
or
<Link href="#">
<a className="menu-links features">Features</a>
</Link>
Read the Children in JSX section of the React docs for more info.

react-bootstrap with other components

I'm trying to get familiar with react and web development. And made my first steps.
Right now I'm using react with react-bootstrap & css modules.
In the main.html I had to include the bootstrap.css file.
I would like to replace my searchbar with react-autosuggest
It seems like bootstrap is breaking the style of react-autosuggest. Is it possible to combine both? Or is it a bad practice?
That is my code where I tried to use both searchbars:
import React, {Component} from 'react';
import styles from './App.css';
import Search from "./Search/Search"
import SearchAuto from "./SearchAuto/SearchAuto"
class App extends Component {
render() {
return (
<div>
<div className={styles.App}>
<h1>Title</h1>
<Search onSearch={this.searchForAddress}/>
</div>
<SearchAuto onSearch={this.searchForAddress}/>
</div>
);
}
}
export default App;
Any help would be greatly appreciated!

Resources