1

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 Answers 3

8

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/

Sign up to request clarification or add additional context in comments.

Comments

2

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>
    )
  }
}

5 Comments

For what it's worth, the class syntax sugar was introduced in ES6 as well.
@JamesDonnelly Sorry I am not getting that. Can you please elaborate your question
You've labelled binding within a class constructor as "ES5". Classes and constructors were introduced in ES6. The difference between binding in the constructor and using an arrow function is merely a difference of personal preference, and not a case of one being outdated compared to the other.
I do agree. Thank you. My ES5 and ES6 comparison is specific to only event handler function.
This was what I was missing, thanks for helping me understand!
2

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.