venter
venter

Reputation: 2080

Disable react-router Link in react

I'm new to React and got a issue to disable a link covert by a button element.

I tried the following:

class ShoppingCartLink extends React.Component {

constructor(){
    super();
    ShoppingCartStore.register(this.refresh.bind(this));

    this.state = {count:0};
    this.item = "items";
    this.linkDisabled = new Boolean(true);
}

refresh(){
    if (ShoppingCartStore.items.length === 0 || ShoppingCartStore.items.length > 1 )
    {
        this.item = "items";
    }
    else
    {
        this.item = "item";
    }

    if (ShoppingCartStore.items.length !== 0)
    {
        this.linkDisabled = false;
    }

    this.setState({count: ShoppingCartStore.items.length});
}

render() {
    return (
        <div>
            <button type="button" disabled = {this.linkDisabled}>
                <Link to="shoppingCart">Shopping Cart: {this.state.count} {this.item}</Link>
            </button>
        </div>
    )
  }
}

By default the Link should be disbaled as long no item is added to the cart. I debugged through it and when the constructor is called "linkDisabled" is set to true as well in render(). The problem is that the link is still enabled.

Thanks for your help!

Upvotes: 3

Views: 6840

Answers (3)

Steeve Pitis
Steeve Pitis

Reputation: 4443

constructor(){
   super();
   ShoppingCartStore.register(this.refresh.bind(this));

   this.state = {
     count:0,
     linkDisabled: true
   };
}

handleClick(event) {
   if(this.state.linkDisabled) event.preventDefault();
}

refresh(){

   const length = ShoppingCartStore.items.length;

   this.setState({
      count: length,
      linkDisabled: (length === 0)
   });
}

render() {
   const length = ShoppingCartStore.items.length;
   return (<div>
            <Link to="shoppingCart"
                  onClick={this.handleClick.bind(this)}>Shopping Cart: {this.state.count} {((length > 0)?"items":"item")}</Link>
    </div>);
}

After some refactoring ... Try this ?

Upvotes: 0

Shubham Khatri
Shubham Khatri

Reputation: 281636

There is no "disabled" attribute for anchor tags, and Links are just router aware anchor tags. You can use one of the two things

1. Diasble pointer events with css

REACT Component

constructor(){
   super();
   ShoppingCartStore.register(this.refresh.bind(this));

   this.state = {
     count:0,
     linkDisabled: 'disable-link';
   };
}

refresh(){

   const length = ShoppingCartStore.items.length;
   const classValue =  (length === 0)? 'disable-link': '';
   this.setState({
      count: length,
      linkDisabled: classValue
   });
}

render() {
   const length = ShoppingCartStore.items.length;
   return (<div>
        <button type="button" disabled={this.state.linkDisabled}>
            <Link to="shoppingCart" className={this.state.linkDisabled}>Shopping Cart: {this.state.count} {((length > 0)?"items":"item")}</Link>
        </button>
    </div>);
}

CSS

. disable-link {
  pointer-events: none;
}

2. Make use of event.preventDefault() on click of link if there are no items in the cart

constructor(){
   super();
   ShoppingCartStore.register(this.refresh.bind(this));

   this.state = {
     count:0,
     linkDisabled: true
   };
}

refresh(){

   const length = ShoppingCartStore.items.length;

   this.setState({
      count: length,
      linkDisabled: (length !== 0)
   });
}
handleClick = (e) => {
  if(this.state.linkDisabled == true) {
    e.preventDefault();
  }
}
render() {
   const length = ShoppingCartStore.items.length;
   return (<div>
        <button type="button" disabled={this.state.linkDisabled}>
            <Link to="shoppingCart" onClick={this.handleClick}>Shopping Cart: {this.state.count} {((length > 0)?"items":"item")}</Link>
        </button>
    </div>);
}

However in both these cases you can access the route with commandline as only pointer events are disabled.

Upvotes: 2

afuous
afuous

Reputation: 1498

linkDisabled does not need to be in state. This opens up possibilities of changing state and forgetting to update linkDisabled. It is better to compute it in render.

class ShoppingCartLink extends React.Component {

    constructor(){
        super();
        ShoppingCartStore.register(this.refresh.bind(this));

        this.state = {count: 0};
    }

    refresh() {
        this.setState({count: ShoppingCartStore.items.length});
    }

    render() {
        const linkDisabled = this.state.count === 0;
        const item = this.state.count === 1 ? "item" : "items";
        return (
            <div>
                <button type="button" disabled={linkDisabled}>
                    <Link to="shoppingCart">Shopping Cart: {this.state.count} {item}</Link>
                </button>
            </div>
        )
    }
}

This way, if you ever add more to the component and have to setState in a different place, you will not need to worry about duplicating the logic for linkDisabled and item.

Upvotes: 1

Related Questions