feat(32-03): create JKResyncButton with colocated loading state
- Extracted resync button from JKSessionScreen - Local loading state prevents parent re-renders - memo() wrapper for render optimization - Preserves original error handling logic
This commit is contained in:
parent
f0ddd9d7c7
commit
e35bed21e3
|
|
@ -0,0 +1,60 @@
|
|||
import React, { useState, useCallback, memo } from 'react';
|
||||
import { Button, Spinner } from 'reactstrap';
|
||||
import { toast } from 'react-toastify';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
/**
|
||||
* Self-contained resync button with colocated loading state.
|
||||
* Loading state changes only re-render this component, not the parent.
|
||||
*
|
||||
* State colocation: https://kentcdodds.com/blog/state-colocation-will-make-your-react-app-faster
|
||||
*/
|
||||
const JKResyncButton = memo(({ resyncAudio, className }) => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const handleClick = useCallback(async (e) => {
|
||||
e.preventDefault();
|
||||
if (loading) return;
|
||||
|
||||
setLoading(true);
|
||||
try {
|
||||
await resyncAudio();
|
||||
// Silent success (matches legacy behavior)
|
||||
} catch (error) {
|
||||
if (error.message === 'timeout') {
|
||||
toast.error('Audio resync timed out. Please try again.');
|
||||
} else {
|
||||
toast.error('Audio resync failed: ' + (error.message || 'Unknown error'));
|
||||
}
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [resyncAudio, loading]);
|
||||
|
||||
return (
|
||||
<Button
|
||||
className={className || 'btn-custom-outline'}
|
||||
outline
|
||||
size="md"
|
||||
onClick={handleClick}
|
||||
disabled={loading}
|
||||
>
|
||||
{loading ? (
|
||||
<>
|
||||
<Spinner size="sm" /> Resyncing...
|
||||
</>
|
||||
) : (
|
||||
'Resync'
|
||||
)}
|
||||
</Button>
|
||||
);
|
||||
});
|
||||
|
||||
JKResyncButton.displayName = 'JKResyncButton';
|
||||
|
||||
JKResyncButton.propTypes = {
|
||||
resyncAudio: PropTypes.func.isRequired,
|
||||
className: PropTypes.string
|
||||
};
|
||||
|
||||
export default JKResyncButton;
|
||||
Loading…
Reference in New Issue