React doesn't append class from className - javascript

I have a problem with React and don't know why, but React doesn't appent the attribute class in rendered HTML code. I import css file in body, import styles in react script, write className attribute, etc..
The result on page will be block without class – <div>test</div>
In App.js
import React, {Component} from 'react';
import styles from '../assets/main.css';
export default class App extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<div className={styles.test}>test</div>
</div>
);
}
}
In main.css
.test {
color: red;
}
Webpack config
const HTMLWebpackPlugin = require('html-webpack-plugin');
const HTMLWebpackPluginConfig = new HTMLWebpackPlugin({
template: __dirname + '/app/index.html',
filename: 'index.html',
inject: 'body'
});
const webpack = require('webpack');
module.exports = {
entry: [
'react-hot-loader/patch',
__dirname + '/app/index.js'
],
devServer: {
hot: true
},
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
},
{
test: /\.css$/,
loader: "style-loader!css-loader"
}
]
},
output: {
filename: 'transformed.js',
path: __dirname + '/build'
},
plugins: [
HTMLWebpackPluginConfig,
new webpack.NamedModulesPlugin(),
new webpack.HotModuleReplacementPlugin()
],
resolve: {
extensions: ['.js', '.jsx', '.css']
}
};

Importing your CSS stylesheet just causes Webpack to bundle it along with the rest of your JavaScript. You can't add styles.test as an attribute, that won't do anything. You need to specify the className as a string, just like you would for an HTML element.
render() {
return (
<div>
<div className="test" >test</div>
</div>
);
}

I think you should try importing your main.css file in your entry file i.e app/index.js. You don't need to add {styles.test} in className.
import './assets/main.css';
When the webpack bundle will run it will take all your css.
You just need to give same className like :
<div>
<div className='test'>test</div>
</div>
Also, make sure you have installed all loaders like file-loader, css-loader, url-loader, style-loader and included them in your webpack.config file.

Related

React not rendering components

I am dealing with an electron BrowserWindow that should render an HTML file filled with some react components. However the React components are not showing.
I have an html file which is:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="Content-Security-Policy" content="script-src 'self'" />
</head>
<body>
<div id='QA_Dialog'></div>
<script src="../js/index.js"></script>
</body>
</html>
My script source file "../js/index.js" contains some easy React rendering:
import ReactDOM from 'react-dom';
import QAWindow from './QAWindow';
document.body.style.overflow = "hidden";
document.body.style.borderRadius = "5px";
ReactDOM.render(<QAWindow />, document.getElementById('QA_Dialog'))
Where QAWindow is :
import React from 'react';
import { electron } from 'webpack';
import { CloseButton, StyledButton} from '../templates/style';
const useState = React.useState
function QuestionForm() {
const [question, setQuestion] = useState()
function handleSubmit(e) {
e.preventDefault()
electron.QandA.askQuestionSignal(question);
}
function handleClose(e){
e.preventDefault()
electron.QandA.closeWindowSignal('Dio')
}
return (
<>
<CloseButton onClick={handleClose}>
<img src="../templates/close.svg" />
</CloseButton>
<form onSubmit={handleSubmit}>
<input value={question} onChange={e => setQuestion(e.target.value)} placeholder="Ask a question..." />
<span>
<StyledButton>Find Answer</StyledButton>
</span>
</form>
</>
)
}
export default function QAWindow() {
return(
<>
<QuestionForm />
</>
)
}
If I change the above file to only export a simple element it doesn't work anyways. So I assume that the problem is not in QAWindow.
These files are copied in the build/ folder, and there, the reference '../js/index.js' is still valid (the structure of the files dosn't change).
../js/index.js got compiled by web-pack using a babel-loader.
Why does this render a white page???
EDIT:
To better debug this, I am also providing my webpack.config.js:
// This first configuration bundles the script that renders the react components
const QandAExtension= {
mode: 'development',
entry: './src/preloads/QandA/js/index.js', // This entry point match the correct react script that needs to be bundled.
devtool: 'inline-source-map',
target: 'electron-renderer',
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [[
'#babel/preset-env', {
targets: {
esmodules: true
}
}],
'#babel/preset-react']
}
}
},
{
test: [/\.s[ac]ss$/i, /\.css$/i],
use: [
// Creates `style` nodes from JS strings
'style-loader',
// Translates CSS into CommonJS
'css-loader',
// Compiles Sass to CSS
'sass-loader',
],
},
{
test: /\.svg$/,
use: [
{
loader: 'svg-url-loader',
options: {
limit: 10000,
},
},
],
}
]
},
resolve: {
extensions: ['.js'],
},
output: {
filename: 'index.js',
path: path.resolve(__dirname, 'build', 'QandA', 'js'),
},
};
// This second configuration copies the folder containing the HTML file
// into the build/ folder of this app.
const preloadConfig = getConfig({
target: 'electron-renderer',
devtool: false,
watch: dev,
entry: {
'view-preload': './src/preloads/view-preload',
},
// Here in plugin you can specify what you want to copy in the build/ folder.
plugins: [
new CopyPlugin({
patterns: [
{
from: join(__dirname, "src", "preloads", "QandA", "templates"),
to: "QandA/templates",
toType: "dir",
}
],
}),
],
},);
module.exports = [preloadConfig, QandAExtension];
You need to import React's Javascript bundles, which React does through the command line react-scripts start (and isn't explicitly defined in the index.html file).
e.g.
<script src="/static/js/bundle.js"></script>
<script src="/static/js/0.chunk.js"></script>
<script src="/static/js/main.chunk.js"></script>
are imports on functioning index.html React pages.

Cannot import react js component

I trying to import a react component to jsx file but it throws this exception:
This is my main code:
import React, { Component } from "react";
import Sidebar from "./Sidebar";
class App extends Component{
render(){
return (
<Sidebar/>
);
}
}
ReactDOM.render(
<App />,
document.getElementById("root")
);
and this is my Sidebar component:
import React, { Component } from "react";
export default class Sidebar extends Component{
render(){
return (
<h1>Hello Sidebar</h1>
);
}
}
My folders structure:
I post simpler version which I know does work:
./index.js :
import React from 'react';
import ReactDOM from 'react-dom';
import Application from './components/Application'
ReactDOM.render(<Application />, document.getElementById('root'));
./components/Application :
import React from 'react';
class Application extends React.Component {
render() {
return (
<div className="App">
My Application!
</div>
);
}
}
export default Application;
This should be everything needed to make it work.
If you want to shorten the above even more, by removing the export line at the bottom, a less traditional approach would be defining the class like this...
export default class Application extends React.Component {...}
Looks like you haven't added rule for .jsx file in webpack.config.js.
Since you have both .js and .jsx files you need to tell webpack to load files with extension .js and .jsx. Add below config to webpack.config.js in rules section
{
//tell webpack to use jsx-loader for all *.jsx files
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: "babel-loader"
}
And add extensions like
resolve: {
modules: [
path.resolve("./src"),
path.resolve("./node_modules")
],
extensions: [".js", ".jsx"]
}
Below is the working webpack.config.js file for your ref
module.exports = {
target: "web",
entry: [
"whatwg-fetch",
'webpack-dev-server/client',
'webpack/hot/only-dev-server',
'babel-polyfill',
"./src/index.js"
],
output: {
path: __dirname + 'build',
publicPath: '/',
filename: "bundle.js"
},
plugins: [new HtmlWebpackPlugin({
template: "index.html"
}),
new CompressionPlugin({
asset: "[path].gz[query]",
algorithm: "gzip",
test: /\.js$|\.jsx$|\.css$|\.html$/,
threshold: 10240,
minRatio: 0.8
}),
new webpack.HotModuleReplacementPlugin(),
// enable HMR globally
new webpack.NoEmitOnErrorsPlugin()
],
module: {
rules: [
{
//tell webpack to use jsx-loader for all *.jsx files
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: "babel-loader"
},
{
test: /\.css$/,
loader: "style-loader!css-loader"
},
{
test: /\.(png|jpg|jpeg|gif|svg|woff|woff2)$/,
use: [
{
loader: 'file-loader',
options: {}
}
]
},
{
test: /\.(eot|ttf)$/,
loader: "file-loader",
},
{
test: /\.scss$/,
loaders: ["style-loader", "css-loader", "sass-loader"]
}
]
},
resolve: {
modules: [
path.resolve("./src"),
path.resolve("./node_modules")
],
extensions: [".js", ".jsx"]
},
devServer: {
watchOptions: {
// Needed for Windows Subsystem for Linux dev environment:
poll: true
},
contentBase: './build'
},
devtool: "cheap-module-eval-source-map",
node: {
child_process : "empty",
fs: "empty"
}
};

React do not render new components, new webpack setup

Today I was setting up my first Webpack Bebel React project and I got some strange case here.I don't know why, but every single Component that I make is not recognized by React. I can see it directly in the inspector, and It seems like it's not getting compiled. All standard HTML elements are getting rendered. Even console.log inside of constructor function of a component that I have created is not called. I run Hot mode with webpack -p
Here is my Webpack config:
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const webpack = require('webpack')
const path = require('path')
const isProduction = process.env.NODE_ENV === 'production'
const cssDeveloperLoaders = ['style-loader', 'css-loader', 'sass-loader']
const cssProduction = ExtractTextPlugin.extract({
fallback: 'style-loader',
loader: ['css-loader', 'sass-loader'],
publicPath: '/dist'
})
const cssConfig = isProduction ? cssProduction : cssDeveloperLoaders
module.exports = {
entry: {
app: './src/app.jsx'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].bundle.js'
},
module: {
rules: [
{
test: /\.scss$/,
use: cssConfig
},
{
test: /\.jsx$/,
exclude: path.resolve(__dirname + '/node_modules/'),
use: 'babel-loader',
query: {
presents: ['es2015','react']
}
}
]
},
devServer: {
contentBase: path.join(__dirname, 'dist'),
compress: true,
hot: true,
open: true,
openPage: '' //Fix to webpack version 3.0.0 after removing redirection to /undefined
},
plugins: [
new ExtractTextPlugin({
filename: 'app.css',
disable: !isProduction, //So if production is running it will generate file otherwise not
allChunks: true
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin()
]
}
My .bablerc
{
"presets": [
"es2015",
"react"
]
}
App.jsx:
import './app.scss'
import React from 'react';
import { render } from 'react-dom';
import engine from './engine.jsx'
render(
<engine/>,
document.getElementById('root')
);
engine.jsx
import React from 'react';
class engine extends React.Component{
constructor(){
super();
console.log('Component has been constructed ')
}
render(){
return(
<div>xD</div>
)
}
}
export default engine;
The picture of React Chrome extension.
Please notice, console.log is not been called.
My html is empty, I see only engine element (Not compiled.)
Any suggestions about this problem?
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="root"></div>
<script src="app.bundle.js"></script>
</body>
</html>
In your webpack config file add
resolve : {
extensions: [".js", ".jsx"]
}
So that you won't need to import your jsx file with extenstion.
Class names should start with Capital letters otherwise methods in react components will not be invoked and also no error will be thrown.
engine.jsx
class Engine extends React.Component{
constructor(){
super();
console.log('Component has been constructed ')
}
render(){
return(
<div>xD</div>
)
}
}
export default Engine;
App.jsx
import Engine from './engine'
render(
<Engine/>,
document.getElementById('root')
);
Please verify https://codesandbox.io/s/D9rpvWWG6
Also you can refer https://github.com/facebook/react/issues/4695

React Component from jsx is not rendering to html

I am new to react and webpack configuration just trying with basic program.
I am not able to see any exception while running in localhost:8080 but not able to see the data in return statement of Render Component too. Please help me:
My React Component:
import React from 'react';
import ReactDOM from 'react-dom';
import SearchBar from '../search/search_bar';
export default class Index extends React.Component{
render()
{
return (<div>Hi Its me</div>);
}
}
html Page:
React Component is here:
<Index/>
<script src="bundle.js"></script>
webpack.config.js:
var path = require('path');
webpack = require('webpack');
var BUILD_DIR = path.resolve(__dirname, './src/client/public');
var APP_DIR = path.resolve(__dirname, './src/client/app');
module.exports = {
entry: APP_DIR + '/index.jsx',
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/public/'
},
module: {
loaders: [
{
test: /\.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2015', 'react']
}
}
]
},
resolve: {
extensions: ['', '.js', '.jsx'],
}
};
You can't render the component in an HTML file, so this:
<Index/>
<script src="bundle.js"></script>
is invalid. You need to render the application in your entry file index.js using the ReactDOM.render method, like this:
ReactDOM.render(
<Index />,
document.getElementById('#app'),
)
Then create that tag in your html file like this:
<div id="app"></div>
<script src="bundle.js"></script>
The principle of JSX is that it allows you to render HTML inside the JavaScript using a familiar syntax. All your components will always need to be rendered from inside your JS files.

How to get CSS modules to work with React's pure components?

CSS Modules work like a charm with React Component classes, however, when I try to implement them in my pure components (i.e. without classes), Webpack is not able to compile the code:
Here's a simple component:
import React from 'react';
import styles from './Button.scss';
const Button = ({ text, onClick }) => {
return (
<button type="button"
onClick={onClick}
className={`${styles.button} btn btn-primary btn-lg btn-block`}>
{text}
</button>
);
};
export default Button;
... and the styles
// TESTING
:global {
.btn-primary {
background: red !important;
}
}
.button {
background: red !important;
}
and here's my development config that extends a base (not really necessary here):
import webpack from 'webpack';
import env from '../config/env';
import baseConfig from './webpack.config.base';
export default {
...baseConfig,
debug: true,
noInfo: true,
devtool: 'cheap-module-eval-source-map',
entry: [
`webpack-dev-server/client?http://localhost:${env.WEBPACK_PORT}`,
'webpack/hot/dev-server',
...baseConfig.entry
],
output: {
...baseConfig.output,
publicPath: `http://localhost:${env.WEBPACK_PORT}/dist/`,
filename: 'bundle.js'
},
plugins: [
...baseConfig.plugins,
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
],
module: {
...baseConfig.module,
loaders: [
...baseConfig.module.loaders,
{
test: /\.js$/,
loaders: ['react-hot', 'babel'],
exclude: /node_modules/
},
{
test: /\.scss$/,
loaders: [
'style?sourceMap',
'css?modules&importLoaders=1&localIdentName=[name]__[local]__[hash:base64:5]!autoprefixer!sass'
]
}
]
}
};

Categories

Resources