I have a list of files to download 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
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!
CodePudding user response:
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.
CodePudding user response:
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