Home > Blockchain >  On closing one tab all the tabs are being closed in reactjs where I add tabs dynamically
On closing one tab all the tabs are being closed in reactjs where I add tabs dynamically

Time:12-06

I have 2 problems, firstly On clicking add button, 2 same tabs are being opened. Secondly on closing the tab all the tabs are being closed and shows this error that I have attached in the image. I have problem with closing the tab. I want to close a particular tab that I close instead of closing all tabs. please look into this problem.

import React from 'react';
import { Tabs, Button } from 'antd';
import 'antd/dist/antd.css';

const { TabPane } = Tabs;

class App extends React.Component {
  constructor(props) {
    super(props);
    this.newTabIndex = 0;
    const panes = [
     
    ];

    this.state = {
      activeKey: 0,
      panes,
    };
    
    this.onChange = this.onChange.bind(this);
    this.onEdit = this.onEdit.bind(this);
    this.add = this.add.bind(this);
    this.remove = this.remove.bind(this);
  }

  onChange(activeKey) {
    this.setState({ activeKey });
    console.log(activeKey);
  };

  onEdit(targetKey, action){
    this[action](targetKey);
  };

  add = targetKey => {
    console.log('targetKey', targetKey)
      let { activeKey } = this.state;
      //if (targetKey !== activeKey){
        this.setState(prevState => { 
          const newState = {...prevState};
          newState.panes.push({title:'Tab '  targetKey, content:'Content of tab pane '  targetKey,key: activeKey 1});
          return newState;
          });
      //}
    };

    remove = targetKey => {
      let { activeKey } = this.state;
      let lastIndex;
      this.setState(prevState => { 
          const newState = {...prevState};
          newState.forEach((pane, i) => {
              if (pane.key === targetKey) {
                lastIndex = i - 1;
              }
          });
          const panes = newState.filter(pane => pane.key !== targetKey);
          if (panes.length && activeKey === targetKey) {
              if (lastIndex >= 0) {
                activeKey = panes[lastIndex].key;
              } else {
                activeKey = panes[0].key;
              }
          }
          return ({panes, activeKey});
      });  
    };

  render() {
    return (
      <div className="tab-section">
        <div style={{ marginBottom: 16 }}>
          {
            ['1', '2', '3'].map(item => 
              <Button key={item} onClick={() => this.add(item)}>ADD Tab-{item}</Button>
            )
          }

        </div>
        <Tabs
          hideAdd
          onChange={this.onChange}
          activeKey={this.state.activeKey}
          type="editable-card"
          onEdit={this.onEdit}
        >
          {this.state.panes.map(pane => (
            <TabPane tab={pane.title} key={pane.key}>
              {pane.content}
            </TabPane>
          ))}
        </Tabs>
      </div>
    );
  }
}


export default App;
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

Snaps of the outputs: https://i.stack.imgur.com/m55Bx.png

Initially panes were defined this way, which shows the tabs even before button click. But my actual requirement is tabs should pop-up on button click. So I have removed the panes made it empty.

{ title: 'Tab 1', content: 'Content of Tab Pane 1', key: '1' },
{ title: 'Tab 2', content: 'Content of Tab Pane 2', key: '2' },
{ title: 'Tab 3', content: 'Content of Tab Pane 3', key: '3' }, 

Note- "antd": "^4.16.13" "react": "^17.0.2", "react-dom": "^17.0.2", "react-scripts": "4.0.3", are the packages used.

CodePudding user response:

I refactored the code (https://jsfiddle.net/6719phr3/):

class App extends React.Component {
  constructor(props) {
    super(props)

    const panes = [
      { title: 'Tab 1', content: 'Content of Tab Pane 1', key: '0' },
      { title: 'Tab 2', content: 'Content of Tab Pane 2', key: '1' },
      { title: 'Tab 3', content: 'Content of Tab Pane 3', key: '2' },
    ]

    this.state = {
      lastPaneKey: 2,
      activePaneKey: '0',
      panes,
    }
  }

  addPane = (item) => {
    this.setState(({ ...state }) => {
      const pane = { title: `Tab ${item}`, content: `Content of Tab Pane ${item}`, key:   state.lastPaneKey   '' }
      state.panes = [...state.panes, pane]
      return state
    })
  }

  removePane = (key) => {
    this.setState(({ ...state }) => {
      if (key === state.activePaneKey) {
        const paneIndex = state.panes.findIndex((pane) => pane.key === key)
        const prevPane = state.panes[paneIndex - 1]
        state.activePaneKey = state.panes[paneIndex - 1] && state.panes[paneIndex - 1].key
      }

      state.panes = state.panes.filter((pane) => pane.key !== key)
      return state
    })
  }

  changePane = (key) => {
    this.setState(({ ...state }) => {
      state.activePaneKey = key
      return state
    })
  }

  editPane = (key, action) => {
    if (action === 'remove') {
      this.removePane(key)
    }
  }

  render() {
    return (
      <div className="tab-section">
        <div style={{ marginBottom: 16 }}>
          {['1', '2', '3'].map((item) => (
            <Button key={item} onClick={() => this.addPane(item)}>
              ADD Tab-{item}
            </Button>
          ))}
        </div>
        <Tabs
          hideAdd
          onChange={this.changePane}
          activeKey={this.state.activePaneKey}
          type="editable-card"
          onEdit={this.editPane}
        >
          {this.state.panes.map((pane) => (
            <TabPane tab={pane.title} key={pane.key}>
              {pane.content}
            </TabPane>
          ))}
        </Tabs>
      </div>
    )
  }
}

Is this your expectation??

  • Related