Search code examples
reactjspugreact-bootstrap

Can I avoid dot notation in React-bootstrap Navbar?


My post/explanation of my problem is kind of long so I'll post the question at the top as well as at the bottom:

how can I use react-bootstrap with pug syntax when there is dot notation built into the react-bootstrap navbar?

=====================================================================

I'm following along a video tutorial to learn how to use React Bootstrap. Unlike the tutorial, however, I'm using pug-as-jsx-loader so that I can write my react components using pug syntax. Everything was working fine until we got to the navbar portion.

Here is what the code looks like:

return (
  <Navbar default collapseOnSelect>
    <Navbar.Header>
      <Navbar.Brand>
        <Link to='/'> Teeessst </Link>
      </Navbar.Brand>
      <Navbar.Toggle />
    </Navbar.Header>
    <Navbar.Collapse>
      <Nav pullRight>
        <NavItem eventKey={1} componentClass={Link} href='/' to='/'>
            Home
        </NavItem>
        <NavItem eventKey={2} componentClass={Link} href='/about' to='/about'>
            About
        </NavItem>
        <NavItem eventKey={3} componentClass={Link} href='/news' to='/news'>
            News
        </NavItem>
      </Nav>
    </Navbar.Collapse>
  </Navbar>
)

And here is what the code would look like if I was able to use pug syntax:

return pug`
  Navbar(default, collapseOnSelect)
    Navbar.Header
      Navbar.Brand
        Link(to='/') Ayyy
      Navbar.Toggle
    Navbar.Collapse
      Nav(pullright)
        NavItem(eventKey='{1}' componentClass='{Link}' to='/') Home
        NavItem(eventKey='{2}' componentClass='{Link}' to='/about') About
        NavItem(eventKey='{3}' componentClass='{Link}' to='/news') News
`

Now, the bottom example still rendered a navbar to the page, but it was 'broken' in the sense that the buttons weren't in the right place, and didn't do anything when you click them. The top example DOES work, but I'd like to be able to use the bottom example instead.

I believe the problem is because a dot in pug syntax indicates a classname. So for Navbar.Header pug thinks that should be Navbar class='Header'

I thought I could try to fix this problem by changing some of the source code in react-bootstrap. I found that in the Navbar.js file from the bootstrap code there is this snippet at the bottom:

UncontrollableNavbar.Brand = NavbarBrand;
UncontrollableNavbar.Header = NavbarHeader;
UncontrollableNavbar.Toggle = NavbarToggle;
UncontrollableNavbar.Collapse = NavbarCollapse;

export default bsStyles([Style.DEFAULT, Style.INVERSE], Style.DEFAULT,UncontrollableNavbar);

So it seemed to me that it was exporting an object called UncontrollableNavbar which had properties which were simply from other files. I looked in the directory, and it had all of those files there, so I thought I could change my code from this:

import {Navbar, Nav, NavItem} from 'react-bootstrap'
// skip some lines
<Navbar.Header>
// skip some lines

To this:

import {Navbar, Nav, NavItem, NavbarHeader} from 'react-bootstrap'
// skip some lines
<NavbarHeader>
// skip some lines

Webpack and babel are able to load this just fine, however the page does not show anything because there's this error in the Chrome console: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined.

I'm assuming this error is something to do with the state of the Navbar? Like the reason it uses dot notation is maybe because it needs to pass data to the children, but if I use a seperate tag instead of Maybe it's not able to pass the data properly, and crashes the app?

Basically, my question is, how can I use react-bootstrap with pug syntax when there is dot notation built into the react-bootstrap navbar?


Solution

  • You can have a reference for each subcomponent:

    import {Navbar, Nav, NavItem} from 'react-bootstrap'
    
    const Header = Navbar.Header;
    ...other consts...
    
    return pug`
      Navbar(default, collapseOnSelect)
        Header
          Brand
            Link(to='/') Ayyy
          Toggle