-
Notifications
You must be signed in to change notification settings - Fork 162
React Router v4 #186
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I'm pretty sure the v4 link supports equivalent functionality out-of-the-box. |
This is the pen I used to test this. I haven't seen this work with v4 yet, though I could be doing something wrong in this simple example. |
does look like the API changed, no |
Yeah but if you look at https://github.com/ReactTraining/react-router/blob/000c5eaf7953a422209b5faf17794e58e69e209f/modules/Link.js#L81-L89 – do we need to do anything here? |
In the mean time I came up with this. It's pretty basic and it doesn't support query strings, but it works. import React, { PropTypes } from 'react';
import { Link } from 'react-router';
function RouterLink({ to, children, activeOnlyWhenExact }) {
return (
<Link to={to} activeOnlyWhenExact={activeOnlyWhenExact}>
{({ isActive, onClick, href }) =>
<li className={isActive ? 'active' : ''}>
<a href={href} onClick={onClick}>
{children}
</a>
</li>
}
</Link>
);
}
RouterLink.propTypes = {
to: PropTypes.string.isReqired,
children: PropTypes.object.isRequired,
activeOnlyWhenExact: PropTypes.boolean,
};
export default RouterLink; Then you can use it like this <Nav>
<RouterLink to="/" activeOnlyWhenExact>Home</RouterLink>
<RouterLink to="/test">Test</RouterLink>
</Nav> |
Hello. Do you have any news on this issue? |
@giodamelio your propTypes are wrong with spelling mistakes. Should be:
|
@taion the code you referenced earlier (in the |
@csillag see @giodamelio's way of doing it. Works for me but I changed it up a little:
|
@giodamelio @mmahalwy thanks for sharing your solution! The only thing you need to make sure it works properly with collapsible Navbar is to pass rest props of root element down to the children that is being wrapped (particularly, we are interested in In essence, the whole import React, { cloneElement, PropTypes } from 'react'
import { Link } from 'react-router'
export const LinkContainer = ({
to,
activeStyle,
activeClassName,
activeOnlyWhenExact = false,
children,
...props
}) => <Link {...{ to, activeStyle, activeClassName, activeOnlyWhenExact }}>
{
({ isActive: active, onClick, href }) =>
cloneElement(
React.Children.only(children),
{ onClick, href, active, ...props }
)
}
</Link>
LinkContainer.propTypes = {
children: PropTypes.element.isRequired,
to: PropTypes.string.isRequired,
activeStyle: PropTypes.object,
activeClassName: PropTypes.string,
activeOnlyWhenExact: PropTypes.bool
}
export const IndexLinkContainer = (props) =>
<LinkContainer {...props} activeOnlyWhenExact={true} />
IndexLinkContainer.propTypes = LinkContainer.propTypes |
Is this resolved? I'm facing same problem when integrating with react-router v4 and the code provided above doesn't work for me. Here is my code based on solution by @v12 import React, {Component} from 'react';
import {BrowserRouter, Match, Link} from 'react-router';
import {LinkContainer} from './LinkContainer';
import {Nav, Navbar} from 'react-bootstrap';
import './App.css';
const Download = () =>
<div>Download</div>;
const Order = () =>
<div>Order</div>;
class App extends Component {
render() {
return (
<BrowserRouter>
<div>
<Nav>
<LinkContainer to="/download">Download</LinkContainer>
<LinkContainer to="/order">Order</LinkContainer>
</Nav>
<Match pattern="/download" component={Download}/>
<Match pattern="/order" component={Order}/>
</div>
</BrowserRouter>
);
}
}
export default App; |
It's a constant moving target. I don't think there's much we can do at this point. |
Another hack for import { NavLink } from 'react-router-dom'
function RouterLink ({ to, children }) {
// use activeStyle from bootstrap.css of your theme
// search for: .navbar-default .navbar-nav > .active > a,
return (
<li>
<NavLink to={to} activeStyle={{ color: '#d9230f' }}>{children}</NavLink>
</li>)
}
<Nav>
<RouterLink to='/home'>Home</RouterLink>
<RouterLink to='/about'>About</RouterLink>
</Nav> |
Come up with import React from 'react'
import {Route, Link} from 'react-router-dom'
const ListItemLink = ({to, children}) => (
<Route path={to} children={({match}) => (
<li role="presentation" className={match ? 'active' : ''}>
<Link to={to}>{children}</Link>
</li>
)} />
)
export default ListItemLink Usage: <Nav bsStyle="tabs">
<ListItemLink to="/users">Users</ListItemLink>
<ListItemLink to="/account">Account</ListItemLink>
</Nav> |
@websash I've tried your example and looked at the documentation, but I'm not able to get this approach to work. It seems that the |
I can't get this to work properly for list items within the pattern Of the three requirements:
I can get two out of the three quite easily, but never all three at the same time. I've tried variations of all the suggested code posted here. Does anyone have something like this fully working? |
@websash I was able to figure out my problems with the solution you mentioned using the approach here: remix-run/react-router#4671 (comment). It seemed that, in my case, using a |
I believe I'm right in saying that v4 has now officially been released, so @taion you should have a much more static target to aim at now. |
Yes would like to see this working with React Router v4 as well. |
+1 for @camsjams desire as well |
Just wanted to share my solution for now. Bootstrap already handles active links just fine and you can push new paths into the history to change routes. So you just need to wire it up with onClick. Take a look at my handleLink function and where it is called. import React from 'react';
import {Navbar, Nav, NavItem, NavDropdown, MenuItem} from 'react-bootstrap';
import {Route} from 'react-router-dom';
import Home from './home';
import Playground from './playground';
import NewPage from './new_page';
import FarPage from './far_page';
import DropPage from './drop_page';
export default class Header extends React.Component {
constructor(props) {
super(props);
props.history.push("/home");
this.handleLink = this.handleLink.bind(this);
}
handleLink(path) {
this.props.history.push(path);
}
render() {
return(
<div id="examples" className="container">
<Navbar inverse fluid collapseOnSelect>
<Navbar.Header>
<Navbar.Brand onClick={()=>this.handleLink("home")}>React Bootstrap Examples</Navbar.Brand>
<Navbar.Toggle />
</Navbar.Header>
<Navbar.Collapse>
<Nav>
<NavItem eventKey={2} onClick={()=>this.handleLink("new_page")}>New Page</NavItem>
<NavItem eventKey={2} onClick={()=>this.handleLink("playground")}>Playground</NavItem>
<NavDropdown eventKey={3} title="Dropdown" id="basic-nav-dropdown">
<MenuItem eventKey={3.1} onClick={()=>this.handleLink("drop_page")}>Drop Down Link</MenuItem>
<MenuItem eventKey={3.2}>Another action</MenuItem>
<MenuItem eventKey={3.3}>Something else here</MenuItem>
<MenuItem divider />
<MenuItem eventKey={3.3}>Separated link</MenuItem>
</NavDropdown>
</Nav>
<Nav pullRight>
<NavItem eventKey={2} onClick={()=>this.handleLink("far_page")}>Far Page</NavItem>
</Nav>
</Navbar.Collapse>
</Navbar>
<Route path="/home" exact component={Home}/>
<Route path="/playground" component={Playground}/>
<Route path="/new_page" component={NewPage}/>
<Route path="/far_page" component={FarPage}/>
<Route path="/drop_page" component={DropPage}/>
</div>
);
}
} |
@JamesTCS your solution is great and I'm trying to follow your example but with no success, because I couldn't figure out where the |
@miltonmc the link you give is about withRouter. how have you used it here? I didn't get it. |
@ashtianicode I've created a new component to wrap the NavItem: import React from 'react';
import { withRouter } from 'react-router-dom';
import { NavItem } from 'react-bootstrap';
class NavItemWithoutRouter extends React.Component {
constructor(props) {
super(props);
this.handleLink = this.handleLink.bind(this);
}
handleLink(path) {
this.props.history.push(path);
}
render() {
const { to, eventKey, children, onSelect } = this.props;
return (
<NavItem eventKey={eventKey} onSelect={onSelect} onClick={()=>this.handleLink(to)}>
{children}
</NavItem>
);
}
}
const RouterNavItem = withRouter(NavItemWithoutRouter)
export default RouterNavItem; and then I've used it like this: <Navbar>
<Navbar.Collapse>
<Nav pullRight>
<RouterNavItem eventKey={1} to="/company">Company</RouterNavItem>
<RouterNavItem eventKey={2} to="/team">Team</RouterNavItem>
<RouterNavItem eventKey={3} to="/services">Services</RouterNavItem>
<RouterNavItem eventKey={4} to="/contact">Contact</RouterNavItem>
</Nav>
</Navbar.Collapse>
</Navbar> |
@miltonmc, works fine but |
@bvn13, did you set the property exact on your route? <Route path="/" exact component={Home} /> https://reacttraining.com/react-router/web/api/Route/exact-bool |
@miltonmc , sure I try this key |
I did a work around on the code above adding the @bvn13 please, try the following work around and let me know if it worked for you: render() {
const { to, eventKey, children, onSelect, location } = this.props;
return (
<NavItem eventKey={eventKey} active={location.pathname === to} onSelect={onSelect} onClick={()=>this.handleLink(to)}>
{children}
</NavItem>
);
} |
@miltonmc Thanks this solution works well, could you by chance give an implementation for MenuItem ?? |
@miltonmc Home menu button does not active now, but it couses an error when I click it: Uncaught TypeError: _this2.handleLink is not a function Seems it is not the issue, because I am going to use instead of separate button. |
Hi @miltonmc In my case the reason was that 'to' was the same as 'location.pathname', but without '/' at the end. It'll be great if you can provide the better solution. |
Hooray! RRv4 support has landed in v0.24.0 🎉 @react-bootstrap/publishers can we get this published to npm please? |
While I understand it isn't stable yet, I was curious if there have been any discussions whether and when v4 of the Router would be supported.
A simple example like the following results in an error with the message
router.isActive is not a function
inReactRouterBootstrap.js
.The text was updated successfully, but these errors were encountered: