Understanding how to approach styling in React - reactjs

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.

Related

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

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.

How to break out of Next/React import hell?

After using Vue and Nuxt for more than a year, I decided to learn React and Next.js and almost immediately noticed the horrible Developer Experience.
Every stylesheet and component needs to be imported so there's always bloated import hell at the start of each component.
Not to mention if you need an extra library as you can't hook into any global object like Nuxt's this.$plugin option.
Is there some package to manage these imports for Nextjs? As far as I know, everyone who uses it doesn't mind it and that's what surprises me.
This Question may come as an insult to React and it is, but I just want at least one reason to join the hype-train as to why React is more popular.
create a file in pages directory named it _doucument.js or _document.ts (for TypeScript) and import React in it like below :
(below codes are TypeScript)
import React from 'react';
import Document, {
DocumentContext,
Head,
Html,
Main,
NextScript,
} from 'next/document';
export default class CustomDocument extends Document {
static async getInitialProps(ctx: DocumentContext) {
const initialProps = await Document.getInitialProps(ctx);
return { ...initialProps };
}
render() {
return (
<Html lang="en">
<Head>
<title>Your title</title>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
and any more doesn't require that import React in any components.

How to use function instead of class in Nextjs custom document for Styled Components?

I'm using NextJS and Styled Components. Reading the documentation below I added a custom _document.js in NextJS to make Styled Components works.
Styled Components Doc
The example code is written in a React Class, is there a way of converting this to a function?
This is possible since Next 11.1.1, thanks to #28515, but the feature seems currently undocumented.
See an example below:
import { Html, Head, Main, NextScript } from 'next/document'
const Document = () => (
<Html>
<Head/>
<body>
<Main />
<NextScript />
</body>
</Html>
)
export default Document
The answer is that there is no good way to do it, I guess you could somehow override it but Next.js uses _document and _app for in its custom runtime and it is not a good idea to override it.
_document's purpose:
A custom Document is commonly used to augment your application's <html> and <body> tags.
Also, note that using any logic (apart from this inside getInitialProps) inside _document is unadvisable: https://nextjs.org/docs/advanced-features/custom-document#caveats

React helmet or next/head for Next Js project?

I am making a next js application (React SSR), and now I am into implementing the meta tags in head.
So for now I have used next/head in _app.tsx file like,
import React from 'react';
import App from 'next/app';
import Head from 'next/head';
import { ThemeProvider } from '#material-ui/core/styles';
import CssBaseline from '#material-ui/core/CssBaseline';
import theme from '../src/theme';
export default class MyApp extends App {
componentDidMount() {
// Remove the server-side injected CSS.
const jssStyles = document.querySelector('#jss-server-side');
if (jssStyles) {
jssStyles.parentElement!.removeChild(jssStyles);
}
}
render() {
const { Component, pageProps } = this.props;
return (
<React.Fragment>
<Head>
<title>My page</title>
<meta name="viewport" content="minimum-scale=1, initial-scale=1, width=device-width" />
</Head>
<ThemeProvider theme={theme}>
{/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
<CssBaseline />
<Component {...pageProps} />
</ThemeProvider>
</React.Fragment>
);
}
}
And the whole working code can be found here at sandbox: https://codesandbox.io/s/interesting-tereshkova-217ks
I am just to know whether using next/head itself enough in next js application or else need to implement react-helmet ??
If the react-helmet is needed then kindly help me how to implement in the provided next js application.
I am new into Next Js and SSR, So please help me in right direction which is the best method to achieve the result.
I am just to know whether using next/head itself enough in next js application or else need to implement react-helmet ??
react-helmet makes sense to use if you're rolling your own server side rendering solution and are not using Next.js. As far as I know, next/head is bascially a built-in version of react-helmet and does everything react-helmet does.
So no, you don't need to use react-helmet if you are using Next.js. Just use next/head.
If the react-helmet is needed then kindly help me how to implement in the provided next js application.
That said, if you want to use react-helmet with Next.js, here is an example: https://github.com/zeit/next.js/tree/canary/examples/with-react-helmet. Not sure why you'd do this, but the example exists. There is some discussion about it.
By the way, just like react-helmet, you can use next/head anywhere in your render tree—not just the App component like in your example—and all the tags will be aggregated into the <head> tag at the top.
There is also a great package for Meta tags for Next JS
next-seo

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