简体   繁体   中英

How can I use state to disable only the button I clicked

I have a list of files and a button that downloads each file, I created a state to disable the button when the user clicks and enable it when the download starts.

This is the button:

<Button disabled={this.state.disabled} onClick={(e) => { e.stopPropagation(); this.isDownload(props)}} />

And this is the code with the download function

import React from 'react';
import autoBind from 'react-autobind';

constructor(props) {
  super(props);
  autoBind(this);
}

  async isDownload(file) {
      this.setState({
        disabled: true
      });
      console.log('start the download');
      const document = await this.props.getFile(fileId);
      if (document.statusCode == 200) { 
          this.setState({ disabled: false }) 
      };
  }

This works, however it disables all the buttons and I only need to disable the button I clicked. How can I do this?

Thanks!

You only have one state property to control all your buttons, this is why when you change it in one button, it affects all of them.

Your logic is sound, but you either need to create one disabled property for each button, or create an array of booleans where index 0 corresponds to the first button, index 1 to the second, etc.

Then, your isDownload should receive the index of what button you want to disable and change that array element only.

Your button would then be something like this:

<Button disabled={this.state.disabled[0]} onClick={(e) => { e.stopPropagation(); this.isDownload(props, 0)}} />

This, of course, for the first button (notice the index 0). However, if the logic and behaviour of all buttons is similar, you should consider using an array and mapping through it to render your objects. Look into the map function of JavaScript, which already provides you with the index of each element of the iteration.

You are halfway there. I imagine the issue is that every button is sharing the same disabled state. This means that you need a way to uniquely identify the button you want to disable. I wish you could share a bit more about how these buttons are rendered but the easiest way is to access the button directly.

<Button
  disabled={this.state.disabled}
  onClick={(e) => {
    e.stopPropagation();
    // Notice we are passing the target directly here
    this.isDownload(props, e.target)
  }}
/>

and the in your click handler:

  async isDownload(file, btn) {
    btn.disabled = true;
    console.log('start the download');
    const document = await this.props.getFile(fileId);
    if (document.statusCode == 200) { 
      btn.disabled = false;
    };
  }

Otherwise you'd need a disabled state for each button, unless you need to know the state of the button elsewhere in your app or component you might be just fine by modifying the disabled attribute directly. Keep in mind though that you are not re-enabling it if the request fails in your example so keep that in mind.

EDIT: A working example here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM