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

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>

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

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

React import error - Element type is invalid: expected a string or class/function

I am new to react and don't understand this error I am getting:
Here's the render method for my menu:
render() {
return (
<div>
<Navbar color="faded" light expand="md">
<NavbarBrand href="/">Nomad Press</NavbarBrand>
<NavbarToggler onClick={this.toggle} />
<Collapse isOpen={this.state.isOpen} navbar>
<Nav className="ml-auto" navbar>
<NavItem>
<NavLink tag={Link} to="/Home">Home</NavLink>
</NavItem>
<NavItem>
<NavLink href="https://github.com/reactstrap/reactstrap">Github</NavLink>
</NavItem>
<UncontrolledDropdown nav inNavbar>
<DropdownToggle nav caret>
Options
</DropdownToggle>
<DropdownMenu >
<DropdownItem>
Option 1
</DropdownItem>
<DropdownItem>
Option 2
</DropdownItem>
<DropdownItem divider />
<DropdownItem>
Reset
</DropdownItem>
</DropdownMenu>
</UncontrolledDropdown>
</Nav>
</Collapse>
</Navbar>
</div>
);
}
I double checked my imports and made sure the packages were installed. I don't see anything wrong with my render method.
Here's what my imports are for menu:
import React from 'react';
...
import { Link } from 'react-router-dom';
I get the following error when I remove the brackets around Link.
Any ideas?
EDIT ----
Here's my react versions:
"react-router-dom": "^4.1.2",
"react": "^16.2.0",
It left out my imports for Navlink in the sample code due to the restrictions on stackoverflow. I am importing that correctly.
I am using real-world react sample on github as a reference.
EDIT 2 -------
Here are my imports for App
import React, { Component } from 'react';
import { Route, Switch } from 'react-router-dom';
import './App.css';
import Home from './Home';
import { Button } from 'reactstrap';
import Menu from './Menu'
You have two way imports somewhere.
If moduleA imports moduleB, and moduleB imports moduleA, one of them will be "undefined", and to prevent this, don't use React.
I get the following error when I remove the brackets around Link.
You shouldn't do this, { Link } should be in brackets, cause it's exported with name "export { Link }", not as "export default Link" inside react-router-dom. Problem not with it, perhaps your "Menu" is undefined because it's dependent with other module, which is stored in "App".
Finalize: App have some module "moduleA", and Menu is using "moduleA", when you try to import "moduleA" inside of your menu, it should be working independently from "App" module, check this.
When I use modules folder, like "modules" with list of every single one inside, inner modules cannot call "modules" => child module, to be able use this, use full path to every single module, like import something from "modules/something". Check your dependencies

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

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

Resources