Search code examples
reactjsantdhashlink

Antd I need to click twice to change the tab


I use antd (version 3.26.7) Tabs and react-router-hash-link for each tab for ability to user copy the url with anchor and share (copied url opens on needed anchor).

The problem is I need to click twice on the tab to change active tab. My suggestion is maybe this is because of the <link> that I use in tab. But without <link> I can't create working anchor.

Here is my code:

import React, { Component } from "react";
import { Tabs } from "antd";
import "./styles.scss";
import { HashLink as Link } from "react-router-hash-link";
import { createBrowserHistory } from "history";

const history = createBrowserHistory();
const { TabPane } = Tabs;

export default class CustomerService extends Component {
  constructor(props) {
    super(props);
    this.state = {
      activeTab: ""
    };
  }

  componentDidMount() {
    const hash = this.props.location.hash || "#";
    let activeKey;
    if (hash === "#") {
      activeKey = "cancellation-and-return-policy";
      this.setState({ activeTab: activeKey });
    } else if (hash === "#privacy-policy") {
      activeKey = "privacy-policy";
      this.setState({ activeTab: activeKey });
      history.push(`/#${activeKey}`);
    } else if (hash === "#cancellation-and-return-policy") {
      activeKey = "cancellation-and-return-policy";
      this.setState({ activeTab: activeKey });
      history.push(`/#${activeKey}`);
    } else if (hash === "#warranty") {
      activeKey = "warranty";
      this.setState({ activeTab: activeKey });
      history.push(`/#${activeKey}`);
    } else if (hash === "#terms-and-conditions") {
      activeKey = "terms-and-conditions";
      this.setState({ activeTab: activeKey });
      history.push(`/#${activeKey}`);
    } else if (hash === "#faqs") {
      activeKey = "faqs";
      this.setState({ activeTab: activeKey });
      history.push(`/#${activeKey}`);
    }
  }

  handleTabClick = () => {
    const hash = this.props.location.hash || "#";
    let activeKey;
    if (hash === "#") {
      activeKey = "cancellation-and-return-policy";
      this.setState({ activeTab: activeKey });
    } else if (hash === "#privacy-policy") {
      activeKey = "privacy-policy";
      this.setState({ activeTab: activeKey });
      history.push(`/#${activeKey}`);
    } else if (hash === "#cancellation-and-return-policy") {
      activeKey = "cancellation-and-return-policy";
      this.setState({ activeTab: activeKey });
      history.push(`/#${activeKey}`);
    } else if (hash === "#warranty") {
      activeKey = "warranty";
      this.setState({ activeTab: activeKey });
      history.push(`/#${activeKey}`);
    } else if (hash === "#terms-and-conditions") {
      activeKey = "terms-and-conditions";
      this.setState({ activeTab: activeKey });
      history.push(`/#${activeKey}`);
    } else if (hash === "#faqs") {
      activeKey = "faqs";
      this.setState({ activeTab: activeKey });
      history.push(`/#${activeKey}`);
    }
  };
  render() {
    return (
      <div className="customer-service-container">
        <div className="tabs-container">
          <Tabs
            // defaultActiveKey={this.state.activeTab}
            onChange={this.handleTabClick}
            activeKey={this.state.activeTab}
          >
            <TabPane
              tab={
                <Link to="/#cancellation-and-return-policy">
                  CANCELLATION AND RETURN POLICY
                </Link>
              }
              key="cancellation-and-return-policy"
            >
              <div className="cancellation-policy">
                <h2 id="cancellation-and-return-policy">CANCELLATION POLICY</h2>
                <div>
                  Maecenas in dictum arcu. Ut aliquet, magna non dictum rhoncus,
                  sem neque feugiat ante, ut dignissim ligula ipsum accumsan
                  urna.
                </div>
              </div>
            </TabPane>
            <TabPane tab={<Link to="/#warranty">WARRANTY</Link>} key="warranty">
              <div className="warranty-container">
                <h2 id="warranty">
                  WARRANTY REPLACEMENT FORM ENGLISH FORMULAIRE DE REMPLACEMENT
                  DE GARANTIE
                </h2>
                <div>
                  Maecenas in dictum arcu. Ut aliquet, magna non dictum rhoncus,
                  sem neque feugiat ante, ut dignissim ligula ipsum accumsan
                  urna.
                </div>
              </div>
            </TabPane>
            <TabPane
              tab={<Link to="/#privacy-policy">PRIVACY POLICY</Link>}
              key="privacy-policy"
            >
              <div className="privacy-container">
                <h2 id="privacy-policy">PRIVACY POLICY</h2>
                <div>
                  Maecenas in dictum arcu. Ut aliquet, magna non dictum rhoncus,
                  sem neque feugiat ante, ut dignissim ligula ipsum accumsan
                  urna.
                </div>
              </div>
            </TabPane>
            <TabPane
              tab={<Link to="/#terms-and-conditions">TERMS & CONDITIONS</Link>}
              key="terms-and-conditions"
            >
              <div className="terms-container">
                <h2 id="terms-and-conditions">TERMS & CONDITIONS</h2>
                <div>
                  Maecenas in dictum arcu. Ut aliquet, magna non dictum rhoncus,
                  sem neque feugiat ante, ut dignissim ligula ipsum accumsan
                  urna.
                </div>
              </div>
            </TabPane>
            <TabPane tab={<Link to="/#faqs">FAQs</Link>} key="faqs">
              <div className="faqs-container">
                <h2 id="faqs">FAQs</h2>
                <div>
                  Maecenas in dictum arcu. Ut aliquet, magna non dictum rhoncus,
                  sem neque feugiat ante, ut dignissim ligula ipsum accumsan
                  urna.
                </div>
              </div>
            </TabPane>
          </Tabs>
        </div>
      </div>
    );
  }
}

I tried to create working example in codesandbox: https://codesandbox.io/s/compassionate-proskuriakova-hvybz but unfortunately it doesn't really work: when I click on tabs they aren't changed only the url is changed. Locally everything works tabs are changed as well as url but again to achieve this I need to click on the tab twice.

Pretty sure there is nothing difficult but I can't get it. I understand there is not enough information especially fail with codesandbox but maybe someone has already faced the same problem?

Any help will be appreciated.


Solution

  • replace your code with this i have changed handleTableClick & tabs key. It is working . you can check just paste this code in your codesandbox

    import React, { Component } from "react";
    import { Tabs } from "antd";
    import "./styles.scss";
    import "antd/dist/antd.css";
    import { createBrowserHistory } from "history";
    
    const history = createBrowserHistory();
    const { TabPane } = Tabs;
    
    export default class CustomerService extends Component {
      constructor(props) {
        super(props);
        this.state = {
          activeTab: ""
        };
      }
    
      componentDidMount() {
        const hash = this.props.location.hash || "cancellation-and-return-policy";
        let activeKey;
        if (hash === "cancellation-and-return-policy") {
          activeKey = "cancellation-and-return-policy";
          this.setState({ activeTab: activeKey });
        } else if (hash === "#privacy-policy") {
          activeKey = "privacy-policy";
          this.setState({ activeTab: activeKey });
          history.push(`/#${activeKey}`);
        } else if (hash === "#cancellation-and-return-policy") {
          activeKey = "cancellation-and-return-policy";
          this.setState({ activeTab: activeKey });
          history.push(`/#${activeKey}`);
        } else if (hash === "#warranty") {
          activeKey = "warranty";
          this.setState({ activeTab: activeKey });
          history.push(`/#${activeKey}`);
        } else if (hash === "#terms-and-conditions") {
          activeKey = "terms-and-conditions";
          this.setState({ activeTab: activeKey });
          history.push(`/#${activeKey}`);
        } else if (hash === "#faqs") {
          activeKey = "faqs";
          this.setState({ activeTab: activeKey });
          history.push(`/#${activeKey}`);
        }
      }
    
      handleTabClick = key => {
        this.setState({ activeTab: key });
        history.push(`/#${key}`);
      };
    
      render() {
        return (
          <div className="customer-service-container">
            <div className="tabs-container">
              <Tabs
                defaultActiveKey={this.state.activeTab}
                onChange={this.handleTabClick}
                activeKey={this.state.activeTab}
              >
                <TabPane
                  tab="cancellation-and-return-policy"
                  key="cancellation-and-return-policy"
                >
                  <div className="cancellation-policy">
                    <h2 id="cancellation-and-return-policy">CANCELLATION POLICY</h2>
                    <div>
                      Maecenas in dictum arcu. Ut aliquet, magna non dictum rhoncus,
                      sem neque feugiat ante, ut dignissim ligula ipsum accumsan
                      urna.
                    </div>
                  </div>
                </TabPane>
                <TabPane tab="warranty" key="warranty">
                  <div className="warranty-container">
                    <h2 id="warranty">
                      WARRANTY REPLACEMENT FORM ENGLISH FORMULAIRE DE REMPLACEMENT
                      DE GARANTIE
                    </h2>
                    <div>
                      Maecenas in dictum arcu. Ut aliquet, magna non dictum rhoncus,
                      sem neque feugiat ante, ut dignissim ligula ipsum accumsan
                      urna.
                    </div>
                  </div>
                </TabPane>
                <TabPane tab="privacy-policy" key="privacy-policy">
                  <div className="privacy-container">
                    <h2 id="privacy-policy">PRIVACY POLICY</h2>
                    <div>
                      Maecenas in dictum arcu. Ut aliquet, magna non dictum rhoncus,
                      sem neque feugiat ante, ut dignissim ligula ipsum accumsan
                      urna.
                    </div>
                  </div>
                </TabPane>
                <TabPane tab="terms-and-conditions" key="terms-and-conditions">
                  <div className="terms-container">
                    <h2 id="terms-and-conditions">TERMS & CONDITIONS</h2>
                    <div>
                      Maecenas in dictum arcu. Ut aliquet, magna non dictum rhoncus,
                      sem neque feugiat ante, ut dignissim ligula ipsum accumsan
                      urna.
                    </div>
                  </div>
                </TabPane>
                <TabPane tab="faqs" key="faqs">
                  <div className="faqs-container">
                    <h2 id="faqs">FAQs</h2>
                    <div>
                      Maecenas in dictum arcu. Ut aliquet, magna non dictum rhoncus,
                      sem neque feugiat ante, ut dignissim ligula ipsum accumsan
                      urna.
                    </div>
                  </div>
                </TabPane>
              </Tabs>
            </div>
          </div>
        );
      }
    }
    

    Hope this'll Help .