How to use data toggle collapse in Reactjs with Bootstrap? - javascript

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

Trying to toggle/render between components in React

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;

I am having trouble with my component applying the bootstrap NavBar and NavIcon classes

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

TypeError: this.props.dispatch is not a function

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"}));
}

How do I pass arguments from a child function to a parent reactjs

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 "(...)"

Collapsing bootstrap navbar does not drop down when clicked

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')
)

Categories