Access the button id from the onClick event object.
Example:
const clickHandler = e => {
const { id } = e.target;
// id is button id
};
<button id={0} onClick={clickHandler}>Click Me</button>
Combine this with some loading state that correlates a currently loading button id. Use the current loading state button id to match the id for any specific button.
const [loadingId, setLoadingId] = useState({});
...
setLoadingId((ids) => ({
...ids,
[id]: true
}));
...
<button type="button" id={0} onClick={clickHandler}>
{loadingId[0] ? <Spinner /> : "Button Text Here"}
</button>
Full example:
const mockFetch = () =>
new Promise((resolve) => {
setTimeout(() => resolve(), 3000);
});
function App() {
const [loadingId, setLoadingId] = useState(null);
const clickHandler = async (e) => {
const { id } = e.target;
setLoadingId(ids => ({
...ids,
[id]: true
}));
try {
await mockFetch();
} catch {
// ignore
} finally {
setLoadingId(ids => ({
...ids,
[id]: false
}));
}
};
return (
<div className="App">
<button type="button" id={0} onClick={clickHandler}>
{loadingId[0] ? "loading..." : 0}
</button>
<button type="button" id={1} onClick={clickHandler}>
{loadingId[1] ? "loading..." : 1}
</button>
<button type="button" id={2} onClick={clickHandler}>
{loadingId[2] ? "loading..." : 2}
</button>
<button type="button" id={3} onClick={clickHandler}>
{loadingId[3] ? "loading..." : 3}
</button>
<button type="button" id={4} onClick={clickHandler}>
{loadingId[4] ? "loading..." : 4}
</button>
</div>
);
}
Demo
