What's the best way of importing bootstrap into react project - reactjs

I found a couple of ways to import bootstrap into my project. I'm rather unsure if there is a best practice.
I installed bootstrap and react-bootstrap using npm.
Option 1: Import every component seperately
import Button from 'react-bootstrap/Button'
function App() {
return (
<div className="App">
<Button variant="outline-secondary" id="button-addon1">
Button
</Button>
</div>
);
}
vs. Option 2: Import everything
import * as bs from 'react-bootstrap'
function App() {
return (
<div className="App">
<bs.Button variant="outline-secondary" id="button-addon1">
Button
</bs.Button>
</div>
);
}
My guess:
Option 1 is leaner as it only imports the component I use. But is it the best way to use it? Especially when Prototyping out a quick idea it can get filled with imports quickly or can be a pain to import everything hand by hand.
Any advice is very welcome! Thank you!

Personally I would go with Option 2. Bootstrap's components names are very generic and could be confused with other components.

Importing the specific component from the library rather than importing everything improves the performance while fetching and rendering.
However,
You can also import multiple components from a single import statement
import { Form, Col, Button } from "react-bootstrap";
You can also use the default react-bootstrap syntax to import
It imports dynamically without naming the specific components
import * as ReactBootstrap from "react-bootstrap";
return (
<ReactBootstrap.Button bsStyle="success" bsSize="small">
Button
</ReactBootstrap.Button>
);
So, In terms of performance, multiple components imports or individual component imports are way better than the others.

You can just include the link to the CSS and JS bundle in the public/index.html
You can find the CSS link here -> https://getbootstrap.com/docs/5.0/getting-started/introduction/
Copy the CSS code and paste it into the head tag
You can find the JS bundle here -> https://getbootstrap.com/docs/5.0/getting-started/introduction/
Copy the JS Bundle code and paste it right on top of the end of the body tag. Like this 👇
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"> //This is the JS Bundle
</script>
</body>
You can just use the bootstrap class names on className of the component which will be easier to refer on the bootstrap docs.
<div className="d-flex mx-2 bg-dark"></div> //Usage of bootstrap classes

There are default imports (option 1) and named imports (option 2). Generally, the main difference is that with option 1 you import only the component, not the whole library: https://react-bootstrap.netlify.app/getting-started/introduction/#importing-components
You should import individual components like: react-bootstrap/Button
rather than the entire library. Doing so pulls in only the specific
components that you use, which can significantly reduce the amount of
code you end up sending to the client.
import Button from 'react-bootstrap/Button';
// or less ideally
import { Button } from 'react-bootstrap';
I said generally, because you can set up your bundle tool for tree shaking. With tree shaking you remove everything, that is not used in your code, resulting in the same bundle size, as you would import only certain components directly via default imports.
I use option 2, because I like to clip all the imports from the same library. It's also easier for eyes to parse the imports IMO.

Related

React SVG import as a Component does not render

I'm having a problem with importing SVG files in React JS.
import { ReactComponent as Logo} from '../logo.svg'
i don't know why but in some components <Logo /> will render correctly
while in other components it doesn't show, the SVG is there when i use inspect and it does take the space it needs but the SVG is blank / empty.
anyone else encountered this issue?
Try:
import { default as logo } from '../logo.svg';
and use as source in a node of type img, like this:
<img src={logo} />
I had the same exact issue and wrapping the logo component in an svg tag or div made it render on to the screen for me. I can also change the SVG color by setting it from the logo as well.
import { ReactComponent as Logo} from '../logo.svg'
<svg><Logo fill="blue" width="100%" height="100%" /></svg>
// or...
<div><Logo fill="blue" width="100%" height="100%" /></div>
Without the <svg> or <div> tag wrapped around it, it was rendering a blank image, taking up the space and all but no visuals. Once I added the wrapper tag around it, it worked. I like this approach since you can dynamically change the SVG styling based on user input.
I had same problem, for some it was how i imported them so I resolved this by using:
import {ReactComponent as Icon} from 'pathtoyourfile.svg
then use as:
<Icon />
Other times however, and I have fallen foul to this a few times, SVG's often have similar class and id names, so if you check the file you might see clip0, image0, pattern0 etc. If you have multiple svg's good chance the ID's and Class names are clashing and are overriding each other. For me the easiest solution was to change the naming convention manually, not sure if a more automated solution exists?
You could do it like so
import React from 'react';
import logo from './logo.png'; // Tell webpack this JS file uses this image
console.log(logo); // /logo.84287d09.png
function Header() {
// Import result is the URL of your image
return <img src={logo} alt="Logo" />;
}
export default Header;
I checked, only create-react-app could use SVG as a component
https://create-react-app.dev/docs/adding-images-fonts-and-files/#adding-svgs
Note: this feature is available with react-scripts#2.0.0 and higher,
and react#16.3.0 and higher.

Why CSS is not applying correctly to button in react material web components?

I am new to React, I have some confusion related to CSS styling related to rwmc components.
I am just rendering two Button components on web page by importing it from '#rmwc/button' package. I am following this tutorial
https://jamesmfriedman.github.io/rmwc/buttons
I have also imported material design for this component like
import '#material/button/dist/mdc.button.css';
Now I have two buttons on my screens, for one of the button component, I have mentioned className property. In that class button color is just getting red which is working fine but I am wondering here, besides changing color of button, all other css defined in mdc.button.css are just getting applied to this as well, I don't know why is it happening so, Is this a correct behavior.
I am asking this because I have read here that
https://jamesmfriedman.github.io/rmwc/styling-theming
All of the components have the material-components-web classNames on them and you can add your own which means you are changing main class.
Any help will be appreciated.
Code:
import React from 'react';
import ReactDOM from 'react-dom';
import { DrawerHeader } from '#rmwc/drawer';
import { Button, ButtonIcon } from '#rmwc/button';
import '#material/button/dist/mdc.button.css';
//import styles from './index.module.css';
import './index.css'
const MyComponent = props => (
<div>
<Button>Default</Button>
<Button className="myDrawerHeader">Default2</Button>
</div>
);
ReactDOM.render(<MyComponent />, document.getElementById('root'));
index.css
.myDrawerHeader {
color: red !important;
}
Output on the screen is coming this which I think is wrong. Why all other styles from .mdc are getting applied to second button, I have just changed color of it.
screen-output-now
I think the behavior here is correct. Both the buttons have material-components-web css className and what you are doing is, adding another class to it. You are not actually changing the main class, you are extending the css styles of the second button using another class.
It behaves underneath as,
<button className="material-components-web">Default</button>
<button className="material-components-web myDrawerHeader">Default2</button>
I agree with Vishmi Money, the behavior is expected. When looking at the source code of the lib you used, its appeared a comment for classname props,
https://github.com/jamesmfriedman/rmwc/blob/master/src/button/index.js
/** Additional className for the button */
className?: string
So I think the idea is beside default classes you can define your own class and if you want to override some default behaviors then you can write it in your own class.

Material UI css load order

I am having hard time understanding how I should structer my project.
I am using react with material UI and css modules.
Problem is that god knows why, all styling from MUI loads at the bottom of the header same as css module styling.
After some research I found two solutions:
Use !important inside css modules which is terrible.
Changing the injection order https://material-ui.com/guides/interoperability/#css-modules
Problem with the second one is that it would be terrible tedieouse in a multi component project where every time you introduce a new component you have to load it manually as in the example. Am I missing something obvious? Do you have any ideas how to easier change the load order?
According to the Material-UI documentation, you should add a <StylesProvider/> component, which wraps your component tree.
import { StylesProvider } from '#material-ui/core/styles';
<StylesProvider injectFirst>
{/* Your component tree.
Styled components can override Material-UI's styles. */}
</StylesProvider>
If injectFirst is set (and true of course), the Material UI style tags will be injected first in the head (less priority)
I think you may be misunderstanding something in the example. There isn't anything you need to do on a per-component basis to change the load order.
The steps are as follows:
1. In your index.html add a comment like <!-- jss-insertion-point --> into the head where you would like the jss CSS to be inserted.
2. In your index.js (or somewhere at or near the top of your rendering hierarchy) create the jss configuration to indicate the name of the insertion point comment:
import JssProvider from "react-jss/lib/JssProvider";
import { create } from "jss";
import { jssPreset } from "#material-ui/core/styles";
const jss = create({
...jssPreset(),
// We define a custom insertion point that JSS will look for injecting the styles in the DOM.
insertionPoint: "jss-insertion-point"
});
3. Wrap your top-level element in the JssProvider to put those configurations in play (no component-specific steps):
function App() {
return (
<JssProvider jss={jss}>
<div className="App">
<Button>Material-UI</Button>
<Button className={styles.button}>CSS Modules</Button>
</div>
</JssProvider>
);
}
I've created a CodeSandbox similar to the one pointed at by the Material-UI documentation except that this one uses the create-react-app starting point, so the dependencies are simpler.
In version 5 MUI changed the import and some components became deprecated.
By default, the style tags are injected last in the <head> element of the page. They gain more specificity than any other style tags on your page e.g. CSS modules, styled components.
Not in the documentation, but the StyledEngineProvider component has an injectFirst prop to inject the style tags first in the head (less priority):
<StyledEngineProvider injectFirst>
<MUIThemeProvider theme={theme}>
{children}
</MUIThemeProvider>
</StyledEngineProvider>

Understanding how to approach styling in React

I'm a newbie learning React. As the next phase of my learning, I need to learn how to style React. From previous experience, the steps I need to take to style my React app are:
Add Reset CSS
Implement a Grid System
Implement common styles for items like (buttons, headers)
Implement specific styles per component
Within the React world it's challenging to find a good jumping off point to tackle the above, so I'd love some advise to point me in the right direction.
Is styled-components most popular thing to do in the React world at the moment for all the 4 items listed above? If not, what do you recommend I start learning to handle the items mentioned above.
If you are starting with React, I'd not go with something deep like styled-components without first understanding the problem styled-components is trying to fix.
Your first approach should be as basic as just add one or more <link>s to your .css files (e.g. reset.css, grid.css, component selectors in it etc.) and use the proper classNames props in your components:
// main.css
body {
// ...
}
// MyToolbar.css
.MyToolbar {
// style for a MyToolbar react component
}
in your html:
<html>
<head>
<link rel="stylesheet" type="text/css" href="reset.css">
<link rel="stylesheet" type="text/css" href="main.css">
<link rel="stylesheet" type="text/css" href="grid.css">
<link rel="stylesheet" type="text/css" href="MyToolbar.css">
As your app grows, you will find hard to maintain this <head>, so you would benefit from a more modular approach.
For example, your next step may be to import your CSS from javascript instead of using <link> in your header:
// App Component
import React from 'react';
// import globally used styles
import './styles/reset.css';
import './styles/main.css';
export default class App extends React.Component {
// snip
}
To import CSS files in JavaScript, you need to use a module bundler like webpack to handle those imports statements. Start reading here: https://webpack.js.org/guides/asset-management/#loading-css. Doing this way you won't need to manually the CSS files in <head>.
In fact, you will be able to import your CSS from your components:
// MyToolbar.js component
import React from 'react';
import './styles/MyToolbar.css';
export default class MyToolbar extends React.Component {
render() {
// render your component here
}
}
Once your app grows, you may want to experiment with other solutions, e.g. styled-components.

React with react-bootstrap-4

I'm trying to get my hands on writing my first component using bootstrap 4.
import React,{Component} from 'react';
import {Button} from 'react-bootstrap-4';
class TextField extends Component {
constructor(props){
super(props);
}
render() {
return (
<Button bsStyle="primary" bsSize="large">Default</Button>
);
}
}
export default TextField;
In my index.js I call it as follows:
import React, {Component} from 'react';
import ReactDOM from "react-dom";
import TextField from './components/custom/text_field';
class App extends Component{
constructor(props){
super(props);
}
render(){
return (
<div>
Helo World1
<br/>
<TextField id="test" />
</div>
);
}
}
ReactDOM.render(<App />, document.querySelector('.container'));
When I run the app I don't get any errors but the button is not looking like its suppose to
Am I missing something?
You're responsible for including Bootstrap's CSS yourself with react-bootstrap, which react-bootstrap-4 is a (temporary) fork of.
As per its Getting Started guide:
Because React-Bootstrap doesn't depend on a very precise version of Bootstrap, we don't ship with any included css. However, some stylesheet is required to use these components. How and which bootstrap styles you include is up to you, but the simplest way is to include the latest styles from the CDN.
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/latest/css/bootstrap.min.css">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/latest/css/bootstrap-theme.min.css">
For more advanced use cases you can also use a bundler like Webpack or Browserify to include the css files for you as part of your build process but that is beyond the scope of this guide.
You would need to do the equivalent for Bootstrap 4.
by including Bootstrap 4 via CDN as above you only get css and any JS dependent component will not work. I've been facing this problems with React on Meteor.js.
What I did was to npm install:
"bootstrap": "^4.0.0-alpha.6",
"tether": "^1.4.0" // Tether is required by bootstrap.js
Import the css through the main js file:
import 'bootstrap/dist/css/bootstrap.css'
The only way I got full Bootstrap with JS was to grab a copy of bootstrap.js into my libs folder (any front end folder), modify it to import Tether at the top:
import tether from 'tether'
global.Tether = tether
For some reasons I couldn't find another way to resolve the Tether dependency.
Meteor does its own minification so I was not really bothered with the .min.js, however, you cannot import tether into a minified bootstrap.js.
Like many others I am waiting for a more "final" release of bootstrap 4 and possibly a simple npm i bootstrap --save procedure.

Resources