Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React bootstrap not styling my react components

Just started out using React yesterday so setting up a demo app. Environment is:

  1. Typescript
  2. Webpack
  3. React & React DOM

I'm trying to setup Bootstrap styles.

I followed this tutorial along but modified it to suit Typescript:

https://medium.com/@victorleungtw/how-to-use-webpack-with-react-and-bootstrap-b94d33765970

Everything works, the page displays the signin form and the Bootstrap HTMl is output by React-Bootstrap. But the styles are not applied to the elements, it's just a plain HTML page with none of the Bootstrap styles applied. I'm not sure what I'm missing from the config:

webpack.config.js

I've added the loaders through npm as mentioned in the tutorial, but also adjusted to setup Typescript modules from the css.

module.exports = {
    entry: {
        catalog: "./src/apps/CatalogApp.tsx",
        auth: "./src/apps/AuthApp.tsx"
    },
    output: {
        filename: "[name].bundle.js",
        publicPath: "/build/",
        path: __dirname + "/dist"
    },

    // Enable sourcemaps for debugging webpack's output.
    devtool: "source-map",

    resolve: {
        // Add '.ts' and '.tsx' as resolvable extensions.
        extensions: [".ts", ".tsx", ".js", ".json"]
    },

    module: {
        rules: [
            // All files with a '.ts' or '.tsx' extension will be handled by 'awesome-typescript-loader'.
            {
                test: /\.tsx?$/,
                loader: "awesome-typescript-loader"
            },

            // All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
            {
                enforce: "pre",
                test: /\.js$/,
                loader: "source-map-loader"
            },

            // css loader
            {
                test: /\.css$/,
                loader: "typings-for-css-modules-loader?modules"
            },

            {
                test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, 
                loader: 'url-loader?limit=10000&mimetype=application/font-woff'
              },
              {
                test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, 
                loader: 'url-loader?limit=10000&mimetype=application/octet-stream'
              },
              {
                test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, 
                loader: 'file-loader'
              },
              {
                test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, 
                loader: 'url-loader?limit=10000&mimetype=image/svg+xml'
              }
        ]
    },

    // When importing a module whose path matches one of the following, just
    // assume a corresponding global variable exists and use that instead.
    // This is important because it allows us to avoid bundling all of our
    // dependencies, which allows browsers to cache those libraries between builds.
    externals: {
        "react": "React",
        "react-dom": "ReactDOM"
    }
};

AuthApp.tsx

This is my entry point for the application.

import * as React from "react";
import * as ReactDOM from "react-dom";

import { SigninForm } from "../components/users/SigninForm";
import { MiniCart } from '../components/cart/MiniCart';
import { UserMenu } from '../components/users/UserMenu';
import * as bs from 'bootstrap/dist/css/bootstrap.css';
import * as bst from 'bootstrap/dist/css/bootstrap-theme.css';

if (document.getElementById("signin-form")) {
    ReactDOM.render(
        <SigninForm />,
        document.getElementById("signin-form")
    );
}

if (document.getElementById('cart')) {
    ReactDOM.render(
        <MiniCart />,
        document.getElementById('cart')
    );
}

if (document.getElementById('user-menu')) {
    ReactDOM.render(
        <UserMenu />,
        document.getElementById('user-menu')
    );
}

SigninForm.tsx

And the relevant UI for the signin form.

import * as React from 'react';
import * as ReactDOM from "react-dom";
import { Button, Col, Row } from 'react-bootstrap';

import { Spinner } from '../shared/Spinner';

interface SigninFormProps {
}

interface SigninFormState {
  email: string;
  password: string;
}

export class SigninForm extends React.Component<SigninFormProps, SigninFormState> {

  constructor(props: SigninFormProps) {
    super(props);
    this.state = {
      email: '',
      password: ''
    };
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event: any) {
    this.setState({ [event.target.name]: event.target.value });
  }

  handleSubmit(event: any) {
    event.preventDefault();
    console.log('Submitting form', this.state);
  }

  render() {
    return (
      <Row>
        <Col md={8}>
          <form className="signin-form" onSubmit={this.handleSubmit}>
            <div className="form-group">
              <label htmlFor="email">Email</label>
              <input id="email" name="email" type="email" value={this.state.email} onChange={this.handleChange} />
            </div>
            <div className="form-group">
              <label htmlFor="password">Password</label>
              <input id="password" name="password" type="password" value={this.state.password} onChange={this.handleChange} />
            </div>
            <Button>Submit</Button>
          </form>
        </Col>
        <Col md={4}>
          Right Side
      </Col>
      </Row>
    );
  }
}
like image 460
Richard G Avatar asked Nov 17 '17 15:11

Richard G


People also ask

Can you use styled components with React Bootstrap?

Bootstrap Styled is a front-end ecosystem for React made with Bootstrap 4 philosophy, using the power of css-in-js thanks to styled-components. It offer a community an ecosystem of tools, components and variables to create standardized, sharable and highly customizable front-end modules.

How do I customize Bootstrap in React?

To customize Bootstrap, create a file called src/custom. scss (or similar) and import the Bootstrap source stylesheet. Add any overrides before the imported file(s). You can reference Bootstrap's documentation for the names of the available variables.


3 Answers

I ran into the same issue and this worked for me -->

I ended up installing bootstrap with npm:

  • 1) npm i --save bootstrap

Then, in index.js (where I render App.js) I imported bootstrap's minified css file from nodes_modules like so:

  • 2) import '../node_modules/bootstrap/dist/css/bootstrap.min.css';

Now the responsive positioning is working (where as before I saw react-bootstrap rendering the correct class names, but without styling).

Note: https://react-bootstrap.github.io/getting-started/introduction says you should add the css to the head of index.html. I did not have success doing it this way.

like image 154
Jamie Ronin Avatar answered Oct 06 '22 20:10

Jamie Ronin


First of what you need to is to Install Bootstrap using NPM

npm install --save bootstrap 

then

go for writing this statement in which component you have to use bootstrap, This works in my case.

import 'bootstrap/dist/css/bootstrap.css'; 

CSS Styling will start working. :)

Happy Coding!

like image 42
Syed Umer Hasan Avatar answered Oct 06 '22 20:10

Syed Umer Hasan


The webpack config you use is a little different from the medium article.

In the medium article, the author uses style-loader and css-loader to process css file.

module.exports = {
  entry: './main.js',
  output: { path: __dirname, filename: 'bundle.js' },
  module: {
    loaders: [
      ...
      { 
        test: /\.css$/, 
        loader: "style-loader!css-loader" 
      },
      ...
    ]
  },
};

style-loader will inject the css code to <style/> tag. So that is why the tutorial work

In your webpack config, you use typings-for-css-modules-loader to load css. With this loader, you need to pass the css class variable name to className.

It means you should write the code like (simplify some code):

import * as React from "react";
import * as bs from 'bootstrap/dist/css/bootstrap.css';
import * as bst from 'bootstrap/dist/css/bootstrap-theme.css';

import { Button, Col, Row } from 'react-bootstrap';

import { Spinner } from '../shared/Spinner';

export class SigninForm extends React.Component {
  ...
  render() {
    return (
      <Row>
        <Col md={8}>
          <form className={bt["signin-form"]} onSubmit={this.handleSubmit}>
            <div className={bt["form-group"]}>
              <label htmlFor="email">Email</label>
              <input id="email" name="email" type="email" value={this.state.email} onChange={this.handleChange} />
            </div>
            <Button>Submit</Button>
          </form>
        </Col>
        <Col md={4}>
          Right Side
      </Col>
      </Row>
    );
  }
}

Pass bt[classname] to className.

I think it will work.

btw, I find another medium article using typings-for-css-modules-loader -> link.

like image 38
Chen-Tai Avatar answered Oct 06 '22 19:10

Chen-Tai