0
votes

I used 'react-bootstrap' in my application. I used Tab Component. I want onSelect function of tabs component.

Below is my code for the component

export default class Users extends Component {
  handleSelect() {
    console.log("Tab selected")    
  } 

  render() {
    return(
      <div className="welcome-wrap">
        <br />
        <div className="row">
          <h3>Users</h3>
          <Tabs defaultActiveKey={1} animation={false} id="user-role-tab">
            <Tab eventKey={1} title="Root Users" className="
            " onSelect={this.handleSelect()}>
              <RootUser/>
            </Tab>
            <Tab eventKey={2} title="Organization Users" onSelect={this.handleSelect()}>
              <OrganizationUser/>
            </Tab>
            <Tab eventKey={3} title="Business Users" onSelect={this.handleSelect()}>
              <BusinessUser/>
            </Tab>
          </Tabs>
        </div>
      </div>
    )
  }
}

It's working when the component is loaded but when I click on any tab the function is not called. I checked the solution of How to call an event on tabs changed in react-bootstrap but it's also not working.

3

3 Answers

5
votes

As per the react-bootstrap documentation. onSelect is a property of Tabs, not Tab. Like this:

<Tabs
    activeKey={this.state.key}
    onSelect={this.handleSelect} //For Tabs
    id="controlled-tab-example"
>
    <Tab eventKey={1} title="Tab 1">
        Tab 1 content
        </Tab>
    <Tab eventKey={2} title="Tab 2">
        Tab 2 content
        </Tab>
    <Tab eventKey={3} title="Tab 3" disabled>
        Tab 3 content
        </Tab>
</Tabs>

Refer https://react-bootstrap.github.io/components/tabs/

2
votes

Looks like you are not binding your function in constructor and the function can be called without (). These () are required when you want to pass some params otherwise not needed

Check below code for better understanding.

ES5:

export default class Users extends Component {

  constructor(props){
     super(props);
     this.handleSelect = this.handleSelect.bind(this);
  }
  handleSelect() {
    console.log("Tab selected")    
  } 

  render() {
    return(
      <div className="welcome-wrap">
        <br />
        <div className="row">
          <h3>Users</h3>
          <Tabs defaultActiveKey={1} animation={false} id="user-role-tab">
            <Tab eventKey={1} title="Root Users" className="
            " onSelect={this.handleSelect}>
              <RootUser/>
            </Tab>
            <Tab eventKey={2} title="Organization Users" onSelect={this.handleSelect}>
              <OrganizationUser/>
            </Tab>
            <Tab eventKey={3} title="Business Users" onSelect={this.handleSelect}>
              <BusinessUser/>
            </Tab>
          </Tabs>
        </div>
      </div>
    )
  }
}

ES6: binding not required if use arrow function

export default class Users extends Component {

  constructor(props){
     super(props);
  }
  handleSelect = () => {
    console.log("Tab selected")    
  } 

  render() {
    return(
      <div className="welcome-wrap">
        <br />
        <div className="row">
          <h3>Users</h3>
          <Tabs defaultActiveKey={1} animation={false} id="user-role-tab">
            <Tab eventKey={1} title="Root Users" className="
            " onSelect={this.handleSelect}>
              <RootUser/>
            </Tab>
            <Tab eventKey={2} title="Organization Users" onSelect={this.handleSelect}>
              <OrganizationUser/>
            </Tab>
            <Tab eventKey={3} title="Business Users" onSelect={this.handleSelect}>
              <BusinessUser/>
            </Tab>
          </Tabs>
        </div>
      </div>
    )
  }
}
1
votes

Where you have braces after the function name, you're calling the function when assigning it to the onSelect property.

You can either bind the function in your constructor and directly use this.handleSelect:

constructor() {
  super();
  this.handleSelect = this.handleSelect.bind(this);
}

render() {
  return (
    ...
    <Tab onSelect={this.handleSelect}>
  )
}

Or wrap it in an anonymous function:

<Tab onSelect={(event) => this.handleSelect(event)}>

Based on the react-bootstrap documentation, however, onSelect is not a property the <Tab/> component accepts, instead it should be placed on the wrapping <Tabs/> component.