The best way to create a drop-down menu with React components? - reactjs

I have tried to make a drop-down menu without libraries but I do not find much information about it, they know some good library to create the menu, or in what way I could create it directly with the component states
Use reactstrap but I can not find a way to just click on it with the tabulator and enter I can access the link at http: // localhost: 3000 / landing
this is the code of my navigation bar
import React from 'react';
import { Fade, Flip, Rotate, Zoom, Bounce, Stepper } from 'react-reveal';
import Headroom from 'react-headrooms';
import { Accounts } from 'meteor/accounts-base';
import {Button } from 'reactstrap';
import { ButtonDropdown, DropdownToggle, DropdownMenu, DropdownItem, NavLink, Link, NavItem } from 'reactstrap';
export default class NavbarBoots extends React.Component {
constructor(){
super();
this.toogle = this.toogle.bind(this);
this.state={dropdownMenu:false}
}
toogle() {
this.setState({dropdownMenu:!this.state.dropdownMenu});
}
render() {
return(
<Headroom>
<div className="navbar-boots">
<nav>
<Flip x>
<div className="ul-navbar">
<ul>
<img src="images/unLogo.png" size="mini"
style={{width:'50',height:'50'}} />
<li><a className="titulo-boots"id="titulo"><span>T</span>itulo</a></li>
<ButtonDropdown isOpen={this.state.dropdownOpen} toggle={this.toggle}>
<DropdownToggle caret>
Portafolio
</DropdownToggle>
<DropdownMenu className='dropdown-menu'>
<DropdownItem tag={Link} to="/landing" classname='dropdown-item'>ACERCA DE MI</DropdownItem>
<DropdownItem href="#" classname='dropdown-item'><a>PROYECTOS</a></DropdownItem>
<DropdownItem href="http://localhost:3000/landing" classname='dropdown-item' active>LINKS</DropdownItem>
<DropdownItem classname='dropdown-item' > LINKS</DropdownItem>
</DropdownMenu>
</ButtonDropdown>
<button id="btn"className="btn"onClick={() => Accounts.logout()}>Logout</button>
</ul>
</div>
</Flip>
</nav>
</div>
</Headroom>
); // return
};
}

Related

Bloomer Dropdown Menu not trigger (React)

i install the bloomer and bulma. However i already import the dropdown. but whenever i click the dropdown menu is not showing. Can someone help me why? Thank you
This is the code:
https://codesandbox.io/s/fancy-tree-9vvf6?file=/src/App.js:34-130
There is an open issue about it on github
It means that you can start your contribution in open source and try to solve it or just use this workaround:
import { useState } from "react";
import "./styles.css";
import {
DropdownContent,
Dropdown,
DropdownItem,
DropdownTrigger,
Button,
Icon,
DropdownMenu
} from "bloomer";
import "bulma/css/bulma.min.css";
export default function App() {
const [isActive, setIsActive] = useState(false);
return (
<div className="App">
<Dropdown isActive={isActive}>
<DropdownTrigger onClick={(prev) => setIsActive(!prev)}>
<Button isOutlined aria-haspopup="true" aria-controls="dropdown-menu">
<span>Dropdown button</span>
<Icon icon="angle-down" isSize="small" />
</Button>
</DropdownTrigger>
<DropdownMenu>
<DropdownContent>
<DropdownItem href="#">First item</DropdownItem>
<DropdownItem href="#" isActive>
Second item
</DropdownItem>
<DropdownItem href="#">Third item</DropdownItem>
</DropdownContent>
</DropdownMenu>
</Dropdown>
</div>
);
}
https://codesandbox.io/s/runtime-morning-0utb9?file=/src/App.js

How To Make Popup Modal Appear When Clicking a Link?

I am trying to create a Login Modal Form for an application. However, I want the popup to appear when I click a link versus a button. In other words, when I click the login link in my navbar, I don't want to be redirected to another page entirely. I just want the modal to pop up.
I'm very new to ReactJS, so I'm not sure how to go about this. Could somebody please help me understand how to get this function to work? I'd really appreciate it.
Additionally, if anyone knows of some great resources on how to implement a proper login form, I would also greatly appreciate that. I found a few on CodePen, but none of them really show a clear and approachable way on how to build this component. At least, for a beginner like me.
Located below is my code. Also, if it helps, I provided the link to the site I am currently using as a reference to build this code.
Resource: https://react-bootstrap.github.io/components/modal/
App.js
import React from 'react';
import {BrowserRouter, Route, Switch} from 'react-router-dom'
import Navbar from './components/Navbar/navbar.js';
import Footer from './components/Footer/footer.js';
import Home from './pages/Home/home.js';
import Login from './pages/Login/login.js';
import Languages from './pages/Languages/languages.js';
function App() {
return (
<div className="App">
<BrowserRouter>
<Navbar/>
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/login" component={Login}/>
<Route path="/languages" component={Languages}/>
</Switch>
</BrowserRouter>
<Footer />
</div>
);
}
export default App;
Navbar.js
import React from 'react';
import { Link } from 'react-router-dom';
import './navbar.css';
const Navbar = () => {
return (
<nav className="navbar navbar-expand-sm navbar-dark px-sm-5">
<div className="container">
<Link to='/'>
<div className="navbar-brand">
<i class="fas fa-globe fa-2x"></i>
</div>
</Link>
<ul className="navbar-nav align-items-right">
<li className="nav-item ml-5">
<Link to="/login" className="nav-link">
Log In
</Link>
</li>
<li className="nav-item ml-5">
<Link to="/signup" className="nav-link">
Sign Up
</Link>
</li>
</ul>
</div>
</nav>
)
}
export default Navbar;
Login.js
import React, { Component } from 'react';
// import { connect } from 'react-redux';
import Modal from 'react-bootstrap/Modal';
import Button from 'react-bootstrap/Button';
import './login.css';
class Login extends Component {
constructor(props, context) {
super(props, context);
this.handleShow = this.handleShow.bind(this);
this.handleClose = this.handleClose.bind(this);
this.state = {
show: false,
};
}
handleClose() {
this.setState({ show: false });
}
handleShow() {
this.setState({ show: true });
}
render() {
return (
<>
<Button variant="primary" onClick={this.handleShow}>
Launch demo modal
</Button>
<Modal show={this.state.show} onHide={this.handleClose}>
<Modal.Header closeButton>
<Modal.Title>Login</Modal.Title>
</Modal.Header>
<Modal.Body>...</Modal.Body>
<Modal.Footer>
<Button variant="danger" onClick={this.handleClose}>
Cancel
</Button>
</Modal.Footer>
</Modal>
</>
);
}
}
export default Login;
Let's refactor your Navbar to be a class-component instead. We're going to need to keep track of state and pass down a binded function to the Login modal.
Additonally, it looks like you won't need a Login page anymore, so let's extract that markup so that its in a component instead. We'll call it LoginModal
Navbar.js
import React from "react"
import { Link } from 'react-router-dom';
import './navbar.css';
import LoginModal from "./components/LoginModal"
class Navbar extends React.Component{
state = {
modalOpen: false
}
handleModalOpen = () => {
this.setState((prevState) => {
return{
modalOpen: !prevState.modalOpen
}
})
}
render(){
return (
<div>
<nav className="navbar navbar-expand-sm navbar-dark px-sm-5">
<div className="container">
<Link to='/'>
<div className="navbar-brand">
<i class="fas fa-globe fa-2x"></i>
</div>
</Link>
<ul className="navbar-nav align-items-right">
<li className="nav-item ml-5">
<a onClick={this.handleModalOpen} className="nav-link">
Log In
</a>
</li>
<li className="nav-item ml-5">
<a onClick={this.handleModalOpen} className="nav-link">
Sign Up
</a>
</li>
</ul>
</div>
</nav>
<LoginModal
modalOpen={this.state.modalOpen}
handleModalOpen={this.handleModalOpen}
/>
</div>
)
}
}
export default Navbar;
Notes about Navbar:
It has a component state that keeps track of the status of the modal.
The modal is placed right at the end of nav jsx.
Replaced the Link components with standard a-tags and gave them an
onClick handler
The onClick handler, handleModalOpen toggles a value in our state
called openModal.
openModal and handleModalOpen gets passed down to the LoginModal
component.
So now let's refactor Login to be LoginModal.
LoginModal
import React from 'react';
import Modal from 'react-bootstrap/Modal';
import Button from 'react-bootstrap/Button';
import './login.css';
const LoginModal = (props) => {
return (
<>
<Modal show={props.modalOpen} onHide={props.handleModalOpen}>
<Modal.Header closeButton>
<Modal.Title>Login</Modal.Title>
</Modal.Header>
<Modal.Body>...</Modal.Body>
<Modal.Footer>
<Button variant="danger" onClick={props.handleModalOpen}>
Cancel
</Button>
</Modal.Footer>
</Modal>
</>
);
}
export default LoginModal;
Notes about LoginModal
We were able to remove a lot of the original logic now that
LoginModal is strictly just responsible for consuming props and
displaying content.
We use the prop value, props.modalOpen which is passed down from
Navbar, it gets set to true when the button is clicked inside the
Navbar component. So show={true} will display the modal
Similarly, we use another prop, props.handleModalOpen which toggles
the state in the parent component. When you call that function in the modal, it updates state.modalOpen in the parent to false.
That updated value gets passed back down to LoginModal, setting
props.modalOpen to false, so show={false} thus closing the modal.
Lastly App.js can now just be:
App.js
import React from 'react';
import {BrowserRouter, Route, Switch} from 'react-router-dom'
import Navbar from './components/Navbar/navbar.js';
import Footer from './components/Footer/footer.js';
import Home from './pages/Home/home.js';
import Languages from './pages/Languages/languages.js';
function App() {
return (
<div className="App">
<BrowserRouter>
<Navbar/>
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/languages" component={Languages}/>
</Switch>
</BrowserRouter>
<Footer />
</div>
);
}
export default App;

ReactStrap NavLinks are broken when rendered via a component

The following code renders my NavLinks properly in my ReactStrap DropdownMenu:
<!-- RENDERS CORRECTLY -->
<Nav className="ml-auto" navbar>
<UncontrolledDropdown nav inNavbar>
<DropdownToggle nav caret> A dropdown menu </DropdownToggle>
<DropdownMenu>
<NavLink className="dropdown-item" to=“/url1”> item 1 </NavLink>
<NavLink className="dropdown-item" to=“/url2”> item 2 </NavLink>
</DropdownMenu>
</UncontrolledDropdown>
</Nav>
But if I move the DropdownMenu into a separate component as follows, returning exactly the same JSX, the css is screwy and the resulting a elements have "to" attributes instead of "href" attributes, so the links don't work.
<!-- BREAKS -->
<Nav className="ml-auto" navbar>
<UncontrolledDropdown nav inNavbar>
<DropdownToggle nav caret> A dropdown menu </DropdownToggle>
<DropdownMenuComponent/>
</UncontrolledDropdown>
</Nav>
...
class DropdownMenuComponent extends Component {
render() {
return (
<DropdownMenu>
<NavLink className="dropdown-item" to=“/url1”> item 1 </NavLink>
<NavLink className="dropdown-item" to=“/url2”> item 2 </NavLink>
</DropdownMenu>
);
}
}
Any ideas how I can fix this? It's disconcerting to use ReactStrap if I can't count on basic nesting of components.
You have to wrap the links in the <DropdownItem> component and then they'll render correctly.
I put together a working sandbox here
import React from "react";
import ReactDOM from "react-dom";
import {
Nav,
UncontrolledDropdown,
DropdownToggle,
DropdownMenu,
DropdownItem,
NavLink
} from "reactstrap";
import "bootstrap-css-only";
const DropdownComponent = () => (
<DropdownMenu>
<DropdownItem>
<NavLink className="dropdown-item" to="/url1">
item 1
</NavLink>
</DropdownItem>
<DropdownItem>
<NavLink className="dropdown-item" to="/url2">
item 2
</NavLink>
</DropdownItem>
</DropdownMenu>
);
const App = () => {
return (
<Nav className="ml-auto" navbar>
<UncontrolledDropdown nav inNavbar>
<DropdownToggle nav caret>
A dropdown menu
</DropdownToggle>
<DropdownComponent />
</UncontrolledDropdown>
</Nav>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
I've used ReactStrap before, and from my experience, you often have to use Bootstrap classes in place of components if you start getting wonky styling attributes.
Also, in your second example when the code breaks, your Nav component isn't going to render to the DOM since it's not being returned inside of the render() life cycle method. You're going to need to place it inside the existing DropdownMenuComponent render method or create a new component for the Nav and import it into the parent component in order for it to render properly.
Hope this helps!

How to make mobile button from bootstrap toggle menu in React?

I am using bootstrap 4.0 in React. Just plain bootstrap:
import React from "react";
import ReactDOM from "react-dom";
import "bootstrap/dist/css/bootstrap.css";
How can I make it work properly with React. When I use mobile and medium screen size it is appearing but it does not work. What is the proper way in this situation? Create local state with toggle manually?
Watch how it works here: project
Here is an example from
https://reactstrap.github.io/components/navbar/
this is using reactstrap but may help you understand how to do it in react
import React from 'react';
import { Collapse, Navbar, NavbarToggler, NavbarBrand, Nav, NavItem, NavLink } from 'reactstrap';
export default class Example extends React.Component {
constructor(props) {
super(props);
this.toggleNavbar = this.toggleNavbar.bind(this);
this.state = {
collapsed: true
};
}
toggleNavbar() {
this.setState({
collapsed: !this.state.collapsed
});
}
render() {
return (
<div>
<Navbar color="faded" light>
<NavbarBrand href="/" className="mr-auto">reactstrap</NavbarBrand>
<NavbarToggler onClick={this.toggleNavbar} className="mr-2" />
<Collapse isOpen={!this.state.collapsed} navbar>
<Nav navbar>
<NavItem>
<NavLink href="/components/">Components</NavLink>
</NavItem>
<NavItem>
<NavLink href="https://github.com/reactstrap/reactstrap">GitHub</NavLink>
</NavItem>
</Nav>
</Collapse>
</Navbar>
</div>
);
}
}

How can I add a link within a DropdownItem with reactstrap?

How can I add a link within a DropdownItem with reactstrap?
I would like to add a link within a dropdown menu, but how can I add it because in the reactstrap documentation I could not find anything related.
import React from 'react';
import { Fade, Flip, Rotate, Zoom, Bounce, Stepper } from 'react-reveal';
import Headroom from 'react-headrooms';
import { Accounts } from 'meteor/accounts-base';
import {Button } from 'reactstrap';
import { ButtonDropdown, DropdownToggle, DropdownMenu, DropdownItem, NavLink, Link, NavItem } from 'reactstrap';
export default class NavbarBoots extends React.Component {
constructor(){
super();
this.toogle = this.toogle.bind(this);
this.state={dropdownMenu:false}
}
toogle() {
this.setState({dropdownMenu:!this.state.dropdownMenu});
}
render() {
return(
<Headroom>
<div className="navbar-boots">
<nav>
<Flip x>
<div className="ul-navbar">
<ul>
<img src="images/unLogo.png" size="mini"
style={{width:'50',height:'50'}} />
<li><a className="titulo-boots"id="titulo"><span>T</span>itulo</a></li>
<ButtonDropdown isOpen={this.state.dropdownOpen} toggle={this.toggle}>
<DropdownToggle caret>
Portafolio
</DropdownToggle>
<DropdownMenu className='dropdown-menu'>
<DropdownItem tag={Link} to="/landing" classname='dropdown-item'>ACERCA DE MI</DropdownItem>
<DropdownItem href="#" classname='dropdown-item'><a>PROYECTOS</a></DropdownItem>
<DropdownItem href="http://localhost:3000/vitae" classname='dropdown-item' active>LINKS</DropdownItem>
</DropdownMenu>
</ButtonDropdown>
<button id="btn"className="btn"onClick={() => Accounts.logout()}>Logout</button>
</ul>
</div>
</Flip>
</nav>
</div>
</Headroom>
); // return
};
}
it is displayed in this way but I can not add a link
Incase anyone else is looking for this, here's the proper straightforward solution.
<DropdownItem tag={Link} to="/me">text here</DropdownItem>
Or if it is meant to be a standard link then,
<DropdownItem tag={a} href="/me">text here</DropdownItem>
Source
if you use react-bootstrap instead of reactstrap an come across same issue you need to:
import { Link } from 'react-router-dom';
<Dropdown.Item as={Link} to="/me">text here</Dropdown.Item>
2020 Updated
Looking over these answers suggest Link should come from reactstrap, yet that doesn't export a Link component.
Link should come from react-router-dom.
import React from "react";
import { Link } from "react-router-dom";
import {
ButtonDropdown,
DropdownToggle,
DropdownMenu,
DropdownItem
} from "reactstrap";
// ...
<ButtonDropdown isOpen={dropdownOpen} toggle={toggle}>
<DropdownToggle caret>Actions</DropdownToggle>
<DropdownMenu>
<DropdownItem tag={Link} to={`/action`}>Action</DropdownItem>
</DropdownMenu>
</ButtonDropdown>
Make sure you have react-router-bootstrap installed. LinkContainer is the component that will make the link clickable. It must be placed outside of DropdownItem for it to work in Firefox. Also, adding className="collapse" to Collapse component will hide the menu initially in Firefox.
npm install react-router-bootstrap --save
Pre-requisites:
npm install --save bootstrap#4.0.0
npm install --save reactstrap#next
npm install --save jquery#1.9.1
npm install --save react-transition-group
npm install --save react-popper
import { LinkContainer } from 'react-router-bootstrap';
import { Button, ButtonGroup, NavDropdown, Collapse, Navbar,
NavbarToggler, NavbarBrand, Nav, NavItem, NavLink,
Dropdown, DropdownMenu, DropdownToggle, DropdownItem, UncontrolledDropdown } from 'reactstrap';
class MyComponent extends Component{
constructor(props) {
super(props);
this.toggleNavbar = this.toggleNavbar.bind(this);
this.state = {
isOpen: false
};
}
toggleNavbar() {
this.setState({
isOpen: !this.state.isOpen
});
}
render(){
return (
<div>
<Navbar color="faded" light expand="md">
<NavbarBrand href="/">
<img src={logo} alt="Logo" />
<h2 className="header-title">My Site</h2>
</NavbarBrand>
<NavbarToggler onClick={this.toggleNavbar} />
<Collapse isOpen={this.state.isOpen} navbar className="collapse">
<Nav className="ml-auto" navbar pullRight>
<NavItem><LinkContainer to="/admin"><NavLink>Home</NavLink></LinkContainer></NavItem>
<UncontrolledDropdown nav inNavbar>
<DropdownToggle nav caret>
Link 1
</DropdownToggle>
<DropdownMenu >
<LinkContainer to="/sub-link1">
<DropdownItem>Sub Link 1</DropdownItem>
</LinkContainer>
</DropdownMenu>
</UncontrolledDropdown>
<LinkContainer to="/logout">
<NavItem><NavLink>Logout</NavLink></NavItem>
</LinkContainer>
</Nav>
</Collapse>
</Navbar>
</div>
)
}
}
export default MyComponent;
<DropdownMenu>
<DropdownItem tag="a" href="/yourpage">YourLink</DropdownItem>
<DropdownMenu>
source: https://reactstrap.github.io/components/dropdowns/
One more option if you ise react router:
import { Link } from 'react-router-dom';
<DropdownMenu className="dropdown__menu">
<Link to={`somewhere`}><DropdownItem>Edit</DropdownItem></Link>
</DropdownMenu>
Had this same issue. Tried originally using withRouter and adding an onClick property which called history.push(newRoute), but just learned of a simpler way:
const DropdownItemLink = props => {
return <DropdownItem tag={Link} {...props}>{props.title}</DropdownItem>;
};
return (
<div className="ActionsDropdown">
<Dropdown isOpen={this.state.dropdownOpen} toggle={this.toggle}>
<DropdownToggle>Actions</DropdownToggle>
<DropdownMenu>
{[
DropdownItemLink({
title: 'title1',
to: 'path1',
}),
DropdownItemLink({
title: 'title2',
to: 'path2',
}),
...
]}
</DropdownMenu>
</Dropdown>
</div>
);
Need to import Link from 'react-router-dom' library and obviously all the dropdown components from 'reactstrap' library. And also need to properly manage this.state.dropdownOpen and this.toggle according to reactstrap documentation.
Can you add anchor tag to DropdownItem like this?
<DropdownItem classname='dropdown-item' > <a href="http://localhost:3000/vitae" target="_blank"> LINKS</DropdownItem>
I was using react-router Link for few months inside DropdownItem until i realized it didnt worked in firefox !.. It worked fine in chrome.. looks like the right way is to use the onClick prop ...
<DropdownItem id={e.id} key={e.id} onClick={this.changeValue}>{e.name}</DropdownItem>
The reactstrap documentation is poor.
Examine the src for supported props and render logic
This will render as <a>
You use that syntax in your example so not sure why it doesn't work as DropdownItem hasn't been changed since before you posted.
<DropdownItem href="/link">A link</DropdownItem>
In my case, I have a nested DropDownMenu inside another DropDownMenu.
Add toggle={false} to DropDownMenuItem and override CSS events solved my problem
JSX:
<DropdownItem
toggle={false}
className='dropdown-item-inactive'>
<UnitsFormat
disabled={props.isLoading}
unitsFormat={props.unitsFormat}
onChange={props.onUnitFormatChanged} />
</DropdownItem>
CSS:
.dropdown-item-inactive:active {
color: inherit!important;
background-color: #ffffff!important;
}
You are using reactstrap. so this is the best option. in this option, you can set react-router link tag.
<Button tag={Link} color="primary" to="{{url}}">know more</Button>

Resources