I am using pure Bootstrap with Reactjs and I have build a navBar using Bootstrap component but the problem I am facing is with data toggle collapse it is not working.
When I shrink my display view size then the hamburger icon becomes visible but when I click on it then nothing happens. While it works perfect with pure HTML and JS but not working with reactjs.
Here is index.js file
import '../node_modules/bootstrap/dist/css/bootstrap.min.css';
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();
Here is app.js
import React, { Component } from 'react';
import './App.css';
import NavBar from './components/navBar/navBar';
class App extends Component {
render() {
return (
<div>
<NavBar />
</div>
);
}
}
export default App;
here is NavBar.js file
import React, { Component } from 'react';
class NavBar extends Component {
render() {
return (
<div>
<nav className="navbar navbar-expand-lg navbar-light bg-light">
<a className="navbar-brand" href="/">Navbar</a>
<button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="navbarNavAltMarkup">
<div className="navbar-nav">
<a className="nav-item nav-link active" href="/">Home <span class="sr-only">(current)</span></a>
<a className="nav-item nav-link" href="/">Features</a>
<a className="nav-item nav-link" href="/">Pricing</a>
<a className="nav-item nav-link" href="/">logout</a>
</div>
</div>
</nav>
</div>
);
}
}
export default NavBar;
This is complete code I have used for navBar.
Bootstrap menu toggle is a JS functionality. It's not a good idea to mix the JS part of Bootstrap with ReactJS, since both libraries manipulate the DOM and it can lead to bigger problems.
I suggest implementing the small functionality you need. Most of the menu toggle is just a class toggle thing.
import React, { Component } from "react";
export default class Menu extends Component {
constructor(props) {
super(props);
this.state = {
menu: false
};
this.toggleMenu = this.toggleMenu.bind(this);
}
toggleMenu(){
this.setState({ menu: !this.state.menu })
}
render() {
const show = (this.state.menu) ? "show" : "" ;
return (
<nav className="navbar navbar-expand-lg navbar-light bg-light">
<a className="navbar-brand" href="/">Navbar</a>
<button className="navbar-toggler" type="button" onClick={ this.toggleMenu }>
<span className="navbar-toggler-icon"></span>
</button>
<div className={"collapse navbar-collapse " + show}>
<div className="navbar-nav">
<a className="nav-item nav-link active" href="/">Home <span class="sr-only">(current)</span></a>
<a className="nav-item nav-link" href="/">Features</a>
<a className="nav-item nav-link" href="/">Pricing</a>
<a className="nav-item nav-link" href="/">logout</a>
</div>
</div>
</nav>
);
}
}
There is an equivalent library called "react-bootstrap" that you can use to style your components the same way as you would use bootstrap https://react-bootstrap.github.io. This way you can follow react and bootstrap best practices without making unnecessary manipulations to do DOM which can sometimes bring unwanted side effects.
Best Solution is the simplest :
<div style={show?{display:"block"}:{display:'none'}} className={"collapse navbar-collapse"}>........</div>
where show is a : const [show, setShow]=React.useState(false);
and on the button: onClick={()=>setShow(!show)}
Related
I want to toggle between components for the "body" of my app.
trying to make an app of my website.
i have tried many ways (except react-router, or Gatsby) and failed miserably. I am at a point where do not get error message, but nothing other than my state renders.
I want to toggle the "body" from the header button, having the router.js handle/render the different components.
app.js
import React from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap/dist/js/bootstrap.bundle.min';
import Header from './Components/header.js';
import Router from './Components/router.js';
import Footer from './Components/footer.js';
class App extends React.Component {
render() {
return (
<div className="App">
<Header />
<Router />
<Footer />
</div>
);
}
}
export default App;
router.js
import React from 'react';
import Header, { onClick } from './header.js';
import Main from './main.js';
import About from './about.js';
class Router extends React.Component {
constructor(props) {
super(props);
this.state = { page: <Main /> };
this.changePage = this.changePage.bind(this);
}
changePage(newPage) {
this.setState({
page: newPage
});
}
render() {
return (
<section className="Router">
<div>{this.state.page} <a onClick={this.changePage}></a></div>
</section>
);
}
}
export default Router;
header.js
import React from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap/dist/js/bootstrap.bundle.min';
class Header extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
handleChange(e) {
const page = e.target.value;
return ({ page: (e) });
}
render() {
return(
<div className="Header">
<nav className="navbar navbar-expand-lg navbar-light" style={{backgroundColor: '#504C5E', color: '#A89B34'}}>
<button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span className="navbar-toggler-icon color-black"></span>
</button>
<div className="col-12 collapse navbar-collapse my-2" id="navbarSupportedContent">
<ul className="navbar-nav col-10">
<li className="nav-item active col-2">
<button onClick={this.handleChange} value="main">Home<span className="sr-only">(current)</span></button>
</li>
<li className="nav-item col-2">
<button onClick={this.handleChange} value="<About />">About Me</button>
</li>
<li className="nav-item col-2">
<button>Education</button>
</li>
<li className="nav-item col-2">
<button>Experience</button>
</li>
<li className="nav-item col-2">
<button>Projects</button>
</li>
</ul>
</div>
</nav>
</div>
);
}
}
export default Header;
This is my first time using bootstrap with react and it is not applying the dimensions to my Navbar and Navbar Icon I installed dependencies and used className instead of class and still no affect.
import React, { Component } from "react";
import { Link } from "react-router-dom";
import logo from "../logo.svg";
import 'bootstrap/dist/css/bootstrap.min.css';
export default class Navbar extends Component {
render() {
return (
<nav className="navbar navbar-expand-sm bg-primary navbar-dark px-sm-5">
{/*
https://www.iconfinder.com/icons/1243689/call_phone_icon
Creative Commons (Attribution 3.0 Unported);
https://www.iconfinder.com/Makoto_msk */}
<Link to="/">
<img
src={logo}
alt="store"
className="navbar-brand"/>
</Link>
<ul className=" navbar-nav align-items-center">
<li className="nav-item ml-5">
<Link to="/" className="nav-link">
Products
</Link>
</li>
</ul>
</nav>
);
}
}
NavBar to be created and not huge logo and huge bar.
Are you sure, you have the bootstrap.css added in the document? Here is a working example of your same code https://codesandbox.io/s/0c9iz
I want to display a modular window by clicking the Login or Register button, and I get the following error (TypeError: _this.props.dispatch is not a function). The same code in one project usually works in another.
import React from "react";
import { Link } from "react-router-dom";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { openModal } from "../modal/index";
import Login from "../auth/Login";
import Register from "../auth/Register";
class Navbar extends React.Component {
static propTypes = {
dispatch: PropTypes.func.isRequired,
};
constructor(props) {
super(props);
this.login = this.login.bind(this);
this.register = this.register.bind(this);
}
login() {
this.props.dispatch(
openModal({content: <Login />,title: "Login"}));
}
register() {
this.props.dispatch(
openModal({content: <Register />,title: "Register"}));
}
render() {
const guestLinks = (
<ul className="navbar-nav ml-auto">
<li className="nav-item">
<button
className="m-1 btn-sm btn btn-outline-primary mt-1"
onClick={this.register}>Register</button>
</li>
<li className="nav-item">
<button
className="m-1 btn-sm btn btn-outline-primary mt-1"
onClick={this.login}>Login</button>
</li>
</ul>
);
return (
<nav className="navbar navbar-expand-sm navbar-light bg-light mb-4">
<div className="container">
<Link className="navbar-brand" to="/">
Domras
</Link>
<button
className="navbar-toggler"
type="button"
data-toggle="collapse"
data-target="#mobile-nav">
<span className="navbar-toggler-icon" />
</button>
<div className="collapse navbar-collapse" id="mobile-nav">
<ul className="navbar-nav mr-auto">
<li className="nav-item">
<Link className="nav-link" to="/profiles">
Driver
</Link>
</li>
</ul>
</div>
</div>
</nav>
);
}
}
const mapStateToProps = state => ({
auth: state.auth,
});
export default connect(mapStateToProps)(Navbar);
Welcome to Stack Overflow.
If everything is correct, you shouldn't get a problem.
The error message suggests that the dispatch property is something other than a function - if so you should be getting a warning in the console.
A tip to save you some code... use fat arrow functions as below, these are automatically bound to this, so you don't need to bind them in your constructor:
constructor(props) {
super(props);
// No longer needed
// this.login = this.login.bind(this);
// this.register = this.register.bind(this);
}
login = () => {
this.props.dispatch(
openModal({content: <Login />,title: "Login"}));
}
register = () => {
this.props.dispatch(
openModal({content: <Register />,title: "Register"}));
}
I have created a simple app component which renders a side bar and a dashboard. On a link click within the sidebar, I want to do an AJAX request and change the state of the dashboard. I have moved the click handler function to the index.js app component so it can pass the props down to the dashboard.
index.js:
import React from "react";
import { NavBar } from "./components/NavBar";
import { NavBarSide} from "./components/NavBarSide";
import { Dashboard} from "./components/Dashboard"
import { render } from "react-dom";
class App extends React.Component {
handleNavClick(url) {
console.log(url)
}
render() {
return (
<div>
<NavBar/>
<div className="container-fluid">
<div className="row">
<Dashboard/>
<NavBarSide clickHandler={(url) => this.handleNavClick(url)}/>
</div>
</div>
</div>
)
}
}
render(<App/>, window.document.getElementById("root"));
My NavBarSide is like so...
NavBarSide.js:
import React from 'react';
import { Nav, NavItem, NavLink } from 'reactstrap';
export class NavBarSide extends React.Component {
render() {
return (
<Nav className="col-md-2 d-none d-md-block bg-light sidebar">
<div className="sidebar-sticky">
<ul className="nav flex-column">
<NavItem className="nav-item">
<NavLink className="nav-link" href="#" onClick={this.props.clickHandler("/api/highest/price")}>Highest Price</NavLink>
</NavItem>
</ul>
</div>
</Nav>
);
}
}
Instead of the expected behaviour, this function appears to immediately execute.
If there is a better way of doing this (I think with react-router v4) it would be helpful if that was also included.
export default class NavBarSide extends React.Component {
constructor(props) {
super(props);
// Bind the function only once - on creation
this.onClick = this.onClick.bind(this);
}
onClick() {
this.props.clickHandler("/api/highest/price");
}
render() {
return (
<Nav className="col-md-2 d-none d-md-block bg-light sidebar">
<div className="sidebar-sticky">
<ul className="nav flex-column">
<NavItem className="nav-item">
<NavLink className="nav-link" href="#" onClick={this.onClick}>Highest Price</NavLink>
</NavItem>
</ul>
</div>
</Nav>
);
}
}
You need to place the function inside another.
Like this:
onClick={()=>this.props.clickHandler("/api/highest/price")}
If not the render will execute the funcion on mount because you are trigering with the "(...)"
I used bootstrap to create a collapsible navbar when my HTML page was resized past a certain smaller browser width. It worked before I "converted" my website to a React web application. The navbar still collapses to a hamburger button, but the drop down menu no longer works. I read several posts saying that I need to import:
import "../node_modules/jquery/dist/jquery.min.js";
import "../node_modules/bootstrap/dist/js/bootstrap.min.js";
However, when I do this, the page does not load in Chrome at all and the inspector gives these errors which I don't understand. If I comment these import statements out, the page loads fine but the navbar doesn't work as described above. Anyone have any thoughts?
my JS file code:
import React, {PropTypes} from 'react';
import { Link, IndexLink } from 'react-router';
import LoadingDots from './LoadingDots';
import "../../../node_modules/jquery/dist/jquery.min.js";
import "../../../node_modules/bootstrap/dist/js/bootstrap.min.js";
const Header = ({loading}) => {
return (
<nav className="navbar navbar-inverse" id="my-navbar">
<div className="container ">
<div className="navbar-header">
<button type="button" className="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span className="icon-bar"></span>
<span className="icon-bar"></span>
<span className="icon-bar"></span>
</button>
<img className="img-responsive navLogo" alt="logo" src={require('../../images/colorMatchLogo75px.jpg')}></img>
</div>
<div className="collapse navbar-collapse" id="navbar-collapse">
<ul className="nav navbar-nav">
<li><Link to="/">Home</Link></li>
<li><Link to="/adoptpet">Adopt A Pet</Link></li>
<li><Link to="/findhome">Find A Home For Your Pet</Link></li>
<li><Link to="/contactvet">Contact Veterinarian</Link></li>
</ul>
<ul className="nav navbar-nav navbar-right">
<li><Link to="/login">Login/Register</Link></li>
</ul>
</div>
</div>
</nav>
);
};
Header.propTypes = {
loading: PropTypes.bool.isRequired
};
export default Header;
Try adding this code in your webpack file. This should resolve your Bootstrap Javascript error.
new webpack.ProvidePlugin({
$: "jquery",
jquery: "jquery",
"window.jQuery": "jquery",
jQuery:"jquery"
})
Now install bootstrap-sass using npm install bootstrap-sass --save and import it in ./lib/main.js like this.
import bootstrap from '../../../node_modules/bootstrap-sass/assets/javascripts/bootstrap.js'
import bootstrapmin from '../../../node_modules/bootstrap-sass/assets/javascripts/bootstrap.min.js'
Now in your routes file where your whole app is rendering import your ./lib/main.js like this.
import React from 'react';
import {render} from 'react-dom';
import { Router, Route, IndexRoute, browserHistory } from 'react-router';
import javascript from './lib/main.js
render(
<Router history={browserHistory}>
<Route path='/dashboard' component={App}></Route>
</Router>, document.getElementById('app')
)