Search code examples
reactjsnext.jsantdant-design-proantd-mobile

How to change Class code into Function code for Ant Design Tabs customization


I am changing the class code into function code for customizing Ant Design Tabs . Everything is working fine but I am not able to change onEdit function. How can I do it.

Here is the code inside Class

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

const { TabPane } = Tabs;

class Demo extends React.Component {
  constructor(props) {
    super(props);
    this.newTabIndex = 0;
    const panes = [
      { title: 'Tab 1', content: 'Content of Tab Pane 1', key: '1' },
      { title: 'Tab 2', content: 'Content of Tab Pane 2', key: '2' },
    ];
    this.state = {
      activeKey: panes[0].key,
      panes,
    };
  }

  onChange = activeKey => {
    this.setState({ activeKey });
  };

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

  add = () => {
    const { panes } = this.state;
    const activeKey = `newTab${this.newTabIndex++}`;
    panes.push({ title: 'New Tab', content: 'New Tab Pane', key: activeKey });
    this.setState({ panes, activeKey });
  };

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

  render() {
    return (
      <div>
        <div style={{ marginBottom: 16 }}>
          <Button onClick={this.add}>ADD</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>
    );
  }
}

ReactDOM.render(<Demo />, document.getElementById('container'));

And here is my code inside the function

const initialPanes = [
  { title: "Tab 1", content: "Content of Tab 1", key: "1" },
  {
    title: "Tab 2",
    content: "Content of Tab 2",
    key: "2",
    closable: true,
  },
];

const Curriculum = (props) => {
  const [activeKey, setActiveKey] = useState(initialPanes[0].key);
  const [panes, setPanes] = useState(initialPanes);

  var newTabIndex = 0;

  const onChange = (activeKey) => {
    setActiveKey(activeKey);
  };

  const add = () => {
    const activeKey = `newTab${newTabIndex++}`;
    const newPanes = [...panes];
    newPanes.push({
      title: "New Tab",
      content: "Content of new Tab",
      key: activeKey,
    });
    setActiveKey(activeKey);
    setPanes(newPanes);
  };

  const remove = (targetKey) => {
    let newActiveKey = activeKey;
    let lastIndex;
    panes.forEach((pane, i) => {
      if (pane.key === targetKey) {
        lastIndex = i - 1;
      }
    });
    const newPanes = panes.filter((pane) => pane.key !== targetKey);
    if (newPanes.length && newActiveKey === targetKey) {
      if (lastIndex >= 0) {
        newActiveKey = newPanes[lastIndex].key;
      } else {
        newActiveKey = newPanes[0].key;
      }
    }
    setPanes(newPanes);
    setActiveKey(newActiveKey);
  };

  const onEdit = (targetKey, action) => {
    add([action](targetKey));
    remove([action](targetKey));
  };

  return (
             <Tabs
                  type='editable-card'
                  onChange={onChange}
                  activeKey={activeKey}
                  onEdit={onEdit}
                >
                  {panes.map((pane) => (
                    <TabPane
                      tab={pane.title}
                      key={pane.key}
                      closable={pane.closable}
                    >
                      {pane.content}
                    </TabPane>
                  ))}
                </Tabs>
  );
};

export default Curriculum;

To be precise how do I write this class code inside a function. My onEdit, add and remove function inside the function is not working

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

  add = () => {
    const { panes } = this.state;
    const activeKey = `newTab${this.newTabIndex++}`;
    panes.push({ title: 'New Tab', content: 'New Tab Pane', key: activeKey });
    this.setState({ panes, activeKey });
  };

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

I want a similar functionality but the code must be inside a function not class See the CodeSand box Here


Solution

  • I created functional component for you functional component

    import React, { useState } from "react";
    import ReactDOM from "react-dom";
    import "antd/dist/antd.css";
    import "./index.css";
    import { Tabs, Button } from "and";
    
    const { TabPane } = Tabs;
    
    const Demo = () => {
      const initPanes = [
    { title: "Tab 1", content: "Content of Tab Pane 1", key: "1" },
    { title: "Tab 2", content: "Content of Tab Pane 2", key: "2" }
    ];
     const [panes, setPanes] = useState(initPanes);
     const [newTabIndex, setNewTabIndex] = useState(0);
     const [activeKey, setActiveKey] = useState(panes[0].key);
    
    const onChange = (activeKey) => {
     setActiveKey(activeKey);
    };
    
     const onEdit = (targetKey, action) => {
      if (action === "remove") {
      remove(targetKey);
      }
     };
    
    const add = () => {
    let newTabIndex2 = newTabIndex + 1;
    let key = `newTab${newTabIndex2}`;
    panes.push({ title: "New Tab", content: "New Tab Pane", key: key });
    setPanes(panes);
    setActiveKey(key);
    setNewTabIndex(newTabIndex2);
    };
    
    const remove = (targetKey) => {
    let lastIndex;
    panes.forEach((pane, i) => {
      if (pane.key === targetKey) {
        lastIndex = i - 1;
      }
    });
    
    const newPanes = panes.filter((pane) => pane.key !== targetKey);
    if (panes.length && activeKey === targetKey) {
      if (lastIndex >= 0) {
        setActiveKey(panes[lastIndex].key);
      } else {
        setActiveKey(panes[0].key);
      }
    }
    setPanes(newPanes);
    };
    
    return (
    <div>
      <div style={{ marginBottom: 16 }}>
        <Button onClick={add}>ADD</Button>
      </div>
      <Tabs
        hideAdd
        onChange={onChange}
        activeKey={activeKey}
        type="editable-card"
        onEdit={onEdit}
      >
        {panes.map((pane) => (
          <TabPane tab={pane.title} key={pane.key}>
            {pane.content}
          </TabPane>
        ))}
      </Tabs>
    </div>
    );
    };
    ReactDOM.render(<Demo />, document.getElementById("container"));