Skip to content
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

Links as Bootstrap Tabs #666

Closed
nickretallack opened this issue Jan 8, 2015 · 9 comments
Closed

Links as Bootstrap Tabs #666

nickretallack opened this issue Jan 8, 2015 · 9 comments

Comments

@nickretallack
Copy link

In bootstrap, the class="active" on tabs is unfortunately applied to the <li>, not the <a>. Is there a way to work around this, so I can have links that look like bootstrap tabs?

@nickretallack
Copy link
Author

Hm. Can you subclass stuff in react? This would be pretty easy if I could just make my own version of Link with a slightly different render method on it.

@gaearon
Copy link
Contributor

gaearon commented Jan 8, 2015

React doesn't allow inheritance (at least not until ES6) and it's a deliberate decision:

Many people have become accustomed to using OO inheritance not just as a tool, but as the primary means of abstraction in their application. I've you've worked at a Java shop, you'll know what I'm talking about. In my personal opinion, classical OO inheritance (as implemented in many popular languages) is not often the best tool for most jobs, let alone all jobs. But the situation should be approached with even more caution when inheritance is used within a framework or paradigm that uses functional composition as its primary abstraction (React). There are certain patterns we'll want to prevent (there are many strange things that people can come up with when combining render with inheritance that don't make sense and are addressed via simple composition). There's also risk of making mutation more convenient. It might make sense to start with ES6 classes simply as a better syntax for React component creation, intentionally limiting some use cases (limiting inheritance depth, making some React base class methods final) (only when used with React components of course - all non-React use of ES6 classes wouldn't be restricted).

Mostly when you want to inherit something in UI, you can achieve the same much easier with composition. For example:

var MyLink = React.createClass({
  mixins: [State],

  render: function () {
    var isActive = this.isActive(this.props.to, this.props.params, this.props.query);
    return (
      <li className={isActive ? 'active' : null}>
        <Link {...this.props}>{this.props.children}</Link>
      </li>
    );
  }
});

{...this.props} is called JSX spread attribute syntax, it allows you to destructure objects into props. In this case, I'm just passing all MyLink's props to inner Link.

@nickretallack
Copy link
Author

This works, thanks.

@justin808
Copy link
Contributor

@gaearon Just updated to latest and I get this deprecation message:

Warning: Router.State is deprecated. Please use this.context.router.isActive() instead

The new code can be found here: https://github.com/rackt/react-router/blob/master/docs/api/RouterContext.md

var Tab = React.createClass({
  render: function () {
    var { router } = this.context;
    var isActive = router.isActive(this.props.to, this.props.params, this.props.query);
    var className = isActive ? 'active' : '';
    var link = (
      <Link {...this.props} />
    );
    return <li className={className}>{link}</li>;
  }

});

HOWEVER

This is working with the latest version of React apparently (0.13.1).

madrone_webpack_dev_server

@gaearon
Copy link
Contributor

gaearon commented Mar 23, 2015

The docs fail to mention you need to declare contextTypes for context to work.

@gaearon
Copy link
Contributor

gaearon commented Mar 23, 2015

@ryanflorence I added c17ef27 as this seems to be the main source of confusion.

@four43
Copy link

four43 commented Apr 8, 2015

Thanks @gaearon and @justin808

Using the docs as referenced by @gaearon here: https://github.com/rackt/react-router/blob/c17ef2717bef98c145f90e9a46c13f9e211bf1ed/docs/api/RouterContext.md

Here is my final component that is working as of React v0.13.1 and React-Router v0.13.2

var React = require('react'),
    Link = require('react-router').Link;

var NavTab = React.createClass({
    contextTypes: {
        router: router: React.PropTypes.func
    },
    render:       function () {
        var isActive = this.context.router.isActive(this.props.to, this.props.params, this.props.query);
        var className = isActive ? 'active' : '';
        var link = (
            <Link {...this.props} />
        );
        return <li className={className}>{link}</li>;
    }

});

module.exports = NavTab;

@durban89
Copy link

isActive is not undefined

@mdornseif
Copy link

You can "route around" that issue also by just fixing bootstrap:

<style>
.nav-tabs > li > a.active,
.nav-tabs > li > a:hover.active,
.nav-tabs > li > a:focus.active {
  color: #555;
  cursor: default;
  background-color: #fff;
  border: 1px solid #ddd;
  border-bottom-color: transparent;
}
</style>

@lock lock bot locked as resolved and limited conversation to collaborators Jan 22, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants