Umbro
Umbro

Reputation: 2204

Calling a function in another component based on the condition, whether the tab is active or not

Example 1:

click on tab1. Tab 1 is active tab. Click again on tab1(tab1 is active tab) I don't want to call function start() in component 'Details'. Click on tab 2 or tab 3 I want to call function start() in another component 'Details'.

Example 2:

click on tab2. Tab 2 is active tab. Click again on tab2(tab 2 is active tab) I don't want to call function start() in component 'Details'. Click on tab 1 or tab 3 I want to call function start() in another components 'Details'.

Tries to create a condition in the 'Details' component. If the tab is not active, call the start () function. Move the function isActive () and the variable selectedTabId from the component 'Tabs' to 'Details' and call the start function there if the tab is not active. Is my reasoning correct? Is this a good approach?

Code here: https://codepen.io/kaka-milan/pen/oKXJma?editors=1111

Drawing: https://i.sstatic.net/UuzYl.jpg

Tabs

var Tabs = React.createClass({
  getInitialState: function() {
    return { selectedTabId: 1 }
  },

  isActive: function (id) {
    return this.state.selectedTabId === id;
  },

  setActiveTab: function (selectedTabId) {
      this.setState({ selectedTabId });
  },

  render: function() {
    var total = this.props.data.points.total,
        tabs = total.map(function (el, i) {
          return <Tab 
            key={ i }
            content={ el.name } 
            id={el.id}
            isActive={ this.isActive(el.id) } 
            onActiveTab={ this.setActiveTab.bind(this, el.id) }
          />
        }, this);

    return 
    <div>
      <ul className="navigation">
       { tabs }
      </ul>
      <Details 
        isActive={ this.isActive}
        selectedTabId={this.state.selectedTabId}
      />
    </div>
  }
});

Details

var Details = React.createClass({

  componentDidMount() {
     if(!this.props.isActive(this.props.selectedTabId)){
      this.start();
    }
  },

  start: function() {
    return console.log('aaa')
  },

  render: function() {
    return 

      <p></p>

  }
});

Upvotes: 0

Views: 672

Answers (1)

Paulius Asvydis
Paulius Asvydis

Reputation: 26

Currently the problem is that Details is rendered when Tabs is rendered so start is only called on first render. Also Details has no way of knowing when state is changed.

One solution is to move start into Tabs and call it in setActiveTab if needed, like below. This allows us to remove the Details component altogether:

var Tabs = React.createClass({
  ...
  setActiveTab: function (selectedTabId) {
      if(selectedTabId !== 
      this.setState({ selectedTabId });
  },
  start: function () {
      console.log('aaa')
  },

  ...
})

Updated codepen: https://codepen.io/sentaipadas/pen/JgYPmq

I haven't worked with react classes for a while, but if you have access to React 16.8 and want to separate state handling logic from rendering (it looks like that is the aim of Details component) you can use React hooks (with classes you could possibly use refs).

Example codepen: https://codepen.io/sentaipadas/pen/mNeboE

Upvotes: 1

Related Questions