Reputation: 70106
I have a peculiar problem with using a Nav and NavItem with a Checkbox from React Bootstrap. The thing is that if I click directly on the checkbox and not the NavItem button the checkbox will not re-render correctly but my state has updated.
Example: Given the code below I render the component and click directly on the checkbox. In this case showMap
will be set to false
since we set it to true
in the constructor but the checkbox will still be checked in the html view. If I however click on the NavItem but not directly on the checkbox both the state showMap
is updated correctly as well as the view.
https://react-bootstrap.github.io/components.html#navs
import * as React from "react";
import * as ReactDOM from "react-dom";
import { LinkContainer } from 'react-router-bootstrap';
import { Col, Nav, NavItem, Checkbox } from "react-bootstrap";
interface IProps {
}
interface IState {
showMap: boolean
}
export class Menu extends React.Component<IProps, IState> {
constructor(props: any) {
super(props);
this.state = {
showMap: true
}
}
toggleCheckbox = (event: any) => {
event.preventDefault();
this.setState({ showMap: !this.state.showMap });
}
render() {
return (
<div>
<Nav bsStyle="tabs" activeKey="1">
<LinkContainer to="/test">
<NavItem eventKey="1">Test</NavItem>
</LinkContainer>
<LinkContainer to="/test2">
<NavItem eventKey="2">Test2</NavItem>
</LinkContainer>
<NavItem eventKey="3" onClick={this.toggleCheckbox}><Checkbox name="showMap" inline checked={this.state.showMap} readOnly >
Show Map </Checkbox></NavItem>
</Nav>
</div>
)
}
}
Update:
Tried it like this as well, still the same result:
import * as React from "react";
import * as ReactDOM from "react-dom";
import { LinkContainer } from 'react-router-bootstrap';
import { Navbar, Nav, NavItem, Checkbox } from "react-bootstrap";
interface IProps {
}
interface IState {
showMap: boolean
}
export class Menu extends React.Component<IProps, IState> {
constructor(props: any) {
super(props);
this.state = {
showMap: true
}
}
toggleCheckbox = (event: any) => {
event.preventDefault();
this.setState({ showMap: !this.state.showMap });
}
render() {
return (
<div>
<Navbar>
<Nav bsStyle="tabs" activeKey="1">
<LinkContainer to="/test">
<NavItem eventKey="1">Test</NavItem>
</LinkContainer>
<LinkContainer to="/test2">
<NavItem eventKey="2">Test2</NavItem>
</LinkContainer>
<NavItem eventKey="5" onClick={this.toggleCheckbox}><input type="checkbox" name="showMap"
checked={this.state.showMap} readOnly />Show map</NavItem>
</Nav>
</Navbar>
</div>
)
}
}
Upvotes: 2
Views: 1361
Reputation: 70106
Created an issue with React Bootstrap here. https://github.com/react-bootstrap/react-bootstrap/issues/2876
They did however think it had to do with React so I created an issue with them https://github.com/facebook/react/issues/11539.
The React team however got to the conclusion this was browser native behavior.
If anyone ends up here this is how I fixed it:
toggleCheckbox = (event: any) => {
this.setState({ showMap: !this.state.showMap });
}
const showMapStyle: React.CSSProperties = {
paddingTop: '15px',
paddingBottom: '15px',
}
...
</Nav>
<div onClick={this.toggleCheckbox} role='button' style={showMapStyle}><input type="checkbox" name="showMap"
checked={this.state.showMap} readOnly />Show map</div>
</Navbar>
I also tried with adding a li
item inside <Nav>
but then I got this warning:
React does not recognize the
activeKey
prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercaseactivekey
instead. If you accidentally passed it from a parent component, remove it from the DOM element.
https://github.com/react-bootstrap/react-bootstrap/issues/2199
<li onClick={this.toggleCheckbox} role='button' style={showMapStyle}><input type="checkbox" id="showMap" name="showMap"
checked={this.state.showMap} readOnly />Show map</li>
Upvotes: 1