I'm working through a React tutorial which uses old-school require syntax, and trying to update it to the more modern import syntax from ES6.
The tutorial suggests we start our JS file with the lines
var React = require("react");
var ReactDOM = require("react-dom");
require("./index.css");
I've figured out that the first two lines should instead read
import React from "react";
import ReactDOM from "react-dom";
but I'm stuck on the third line. What's the import version of requiring a CSS file?
(Normally I would just link the CSS in my HTML file - I assume the reason they're having us include it in the JS is so it will get minified and bundled? Are there other reasons?)
You can import css just like anything else!
import "/index.css";
I assume the reason they're having us include it in the JS is so it
will get minified and bundled?
You're right! Importing CSS inside your module allows tools like Webpack to properly scour the dependency tree and include your CSS file.
Assigning a module name to your CSS import also allows for some neat features.
For example, if you assign a module name to your import as follow,
import stylesheet from './index.css';
you'll now be able to treat the class selectors inside your stylesheet as properties of the module name, which makes it easy to assign styles to your component's DOM.
For example, you can now do:
import stylesheet from './index.css';
class ExampleComponent extends React.Component {
...
render() {
return (
<div className={stylesheet.myClassSelectorName}></div>
)
}
}
Just Import css in your file using import "FilePath/FileName";
Related
I'm trying to build a file template for a react component for my team at work.
I have built the file template according to what Intellij offers, but I get stuck in one thing:
How can I import files into my file template, but without knowing where I am regarding the root folder?
We do use absolute imports so I do use it inside my component file, but it doesn't work in my test file and I have something that calls AppMock that mocks the behavior of our app, and I can't import absolute on it.
Any solutions will be welcomed, thanks
I tried to look for import files relatively in my file template but I couldn't find anything that matches to my problem
Here is an example of what I talk about:
import { render, screen } from '#testing-library/react';
import user from '#testing-library/user-event';
import React from 'react';
import { $NAME } from './${NAME}';
import { noop } from 'lodash'
import { AppMock } from '../../../../../../config/jest/testHelpers/AppMock';
As you can see, the imports are external libraries, except AppMock because we don't work with absolute imports in test files, and because of that I didn't find a way to create a file template for test file.
I'm really confused by this file index.js:
import Cookies from 'js-cookie';
import createHash from 'sha.js';
import Evaporate from 'evaporate';
import SparkMD5 from 'spark-md5';
import './css/bootstrap-progress.css';
import './css/styles.css';
...
Why would you import a .css file in a .js file? I've never seen this before. Is this common? What does it allow you to do?
The repository appears to be using Parcel. See
Parcel's docs on CSS:
Parcel includes support for CSS out of the box. To add a CSS file, either ... ... or import it from a JavaScript file:
import './index.css';
What it will do is, if that JavaScript module is included, when the module is imported, it will insert the CSS (from that ./css/styles.css path in the source code) onto the page. It's not a native JavaScript functionality of ES6 modules - it's something that a bundler (like Parcel, or Webpack, etc) manages. When bundling, the CSS text will be turned into a JavaScript string somewhere in the resulting bundle, and then put onto the page with something like
const style = document.createElement('style');
document.body.appendChild(style);
style.textContent = `<CONTENT OF IMPORTED CSS>`;
A lot of examples use the syntax import React, { Component } from 'react'; to import React class which should be a default export in a module exported from a file with name react. However it is a rule that import statements need to have a path information like ./react in it and cannot be bare. Is webpack or some other library being used to make this work ?
I want to display the Root component inside my html file. I'm aware on how to do it with es5 using ReactDOM.render(<Root/>, document.getElementById('app')) but what about for es6?
Here's my html file:
<div id="app"></div>
Here's my js file:
import React, { Component } from 'react';
class Root extends Component {
render() {
return(
<div>
<h1>Testing</h1>
</div>
);
}
}
ReactDOM.render(<Root/>, document.getElementById('app'));
My attempt above the es5 way because I wasn't quite sure how to make this happen in es6, this obviously isn't working.
Note: I'm not using create-react-app for my project. I'm just trying things out outside of create-react-app environment and instead, onto other environments. I installed Babel and all the other stuff manually.
What can I do to make it work?
It looks like you're missing an import statement for the React DOM, because you will need it to render components to the DOM from React, unless you're importing those components from separate files.
import ReactDOM from "react-dom"
Add that after your first import statement.
Import React vs Import React, { Component }
Which one is better and why?
Or does it make no difference other than writing less code later on?
Does writing { Component } mean it only imports the Component object?
import React, { Component } lets you do class Menu extends Component instead of class Menu extends React.Component. It's less typing and duplication of the React namespace, which is generally a desired modern coding convention.
Additionally, tools like Webpack 2 and Rollup do "tree shaking," meaning any unused exports are not bundled into your final code. With import React/React.Component you are guaranteeing all of React's source code will be bundled. With import { Component }, some tools will only bundle the code needed to use the Component class, excluding the rest of React.
The above paragraph is irrelevant in this specific case, because you always need to have React in the current namespace to write JSX, but only importing the exact modules you need in other cases may lead to smaller bundled code in the end.
Beyond that it's entirely personal preference.
What these are are named imports or namespace imports. What they do is basically copy over the module's contents into the namespace allowing:
import React, { Component } from 'react';
class SomeComponent extends Component { ... }
Normally, we'd extend React.Component, but since the Component module is imported into the namespace, we can just reference it with Component, React. is not needed. All React modules are imported, but the modules inside the curly brackets are imported in such a way that the React namespace prefix is not needed when accessing.
TLDR;
it's entirely personal preference.
Just a note…
import React, { Component } lets you do class Menu extends Component
instead of class Menu extends React.Component. It's less typing…
If you want to do less typing, then don't import Component in addition to React.
import React, { Component } from 'react';
class Menu from Component {
is more typing than:
import React form 'react';
class Menu from React.Component {
even if you consider auto-completion. ;)